RecyclerView的notifyDataSetChanged()方法没有生效。

4

我正在尝试使用notifyDataSetchanged()在updateList()中更新我的适配器。但是对于recyclerview不起作用。我可以在updateList()中看到列表大小,并显示实际结果,但只有reclerview没有更新。这个类是按照MVVM设计模式设计的。

   public class TasksAdapter extends RecyclerView.Adapter<TasksAdapter.TasksAdapterViewHolder> {
        private static final String TAG =  TasksAdapter.class.getSimpleName();
        static ArrayList<ItemModel> list;
        static Context mContext;
        private Fragment fragment;
        private int row_index = -1;
        private SessionManager session;
    //    SelectColorVM colorVM;

        public TasksAdapter(Fragment fragment, Context context, ArrayList<ItemModel> itemList) {
            this.mContext = context;
            this.list = itemList;
            this.fragment = fragment;
            session = new SessionManager(fragment.getContext());
        }

        public void updateList(ArrayList<ItemModel> itemList){
            list.clear();
            this.list = itemList;
            notifyDataSetChanged();
        }

        @Override
        public TasksAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            TasksItemBinding binding =
                    DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.tasks_item,
                            parent, false);
            return new TasksAdapter.TasksAdapterViewHolder(binding);
        }

        @Override
        public void onBindViewHolder(TasksAdapterViewHolder holder, final int position) {
            holder.binding.setViewModel(list.get(position));
            if(position == 0 && list.get(position).btnText.get().toString().length() > 0)
                holder.binding.btnUpdate.setVisibility(View.VISIBLE);
            else
                holder.binding.btnUpdate.setVisibility(View.INVISIBLE);
            holder.binding.layoutItem.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    //                row_index = position;
    //                notifyDataSetChanged();
                    Fragment fragment = new DetailFragment();
                    FragmentManager manager = ((FragmentActivity) mContext).getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = manager.beginTransaction();
                    Bundle bundle = new Bundle();
                    ItemModel item = list.get(position);
                    bundle.putSerializable("item", item);
                    fragment.setArguments(bundle);
                    fragmentTransaction.replace(R.id.id_frame, fragment, "details");
                    fragmentTransaction.addToBackStack("details");
                    fragmentTransaction.commit();
                }
            });
            holder.binding.btnUpdate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    HashMap<String, String> user = session.getUserDetails();
                    if(list.get(position).btnText.get().equals("Task Start")){
                        LandingEngine.updateStatusAndSetStartTimeForRequest(fragment, user.get(SessionManager.KEY_CLEANER_ID), list.get(position).sid.get().toString());
                    } else if(list.get(position).btnText.get().equals("Task Complete")){
                        LandingEngine.updateStatusAndSetCompleteTimeForRequest(fragment, user.get(SessionManager.KEY_CLEANER_ID), list.get(position).sid.get().toString());
                    }
                }
            });
        }

        @Override
        public int getItemCount() {
            return list.size();
        }

        public static class TasksAdapterViewHolder extends RecyclerView.ViewHolder {
            TasksItemBinding binding;

            public TasksAdapterViewHolder(TasksItemBinding rowbinding) {
                super(rowbinding.getRoot());
                this.binding = rowbinding;
            }

        }
        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public int getItemViewType(int position) {
            return position;
        }


    }

我正在像下面这样从我的片段调用适配器:
if(list.size() > 0) {
            if(adapter == null) {
                view.setHasFixedSize(true);
                mLayoutManager = new LinearLayoutManager(fragment.getContext());
                view.setLayoutManager(mLayoutManager);
                adapter = new TasksAdapter(fragment, fragment.getContext(), list);
                view.setAdapter(adapter);
                view.addItemDecoration(new DividerItemDecoration(fragment.getContext()));
            } else {
                adapter.updateList(list);
//                view.getAdapter().notifyDataSetChanged();
//                view.invalidate();
            }
        }

请检查这个,让我知道我哪里出错了。提前致谢。

为什么在 updateList(list); 中使用 **list.clear();**? - AskNilesh
这只是为了删除列表中先前分配的数据。 - malli
将此行代码 view.setHasFixedSize(true); 删除,否则将其改为 false。 - mehul chauhan
谢谢回复@mehul,但没有运气。 - malli
@malli 解决了吗? - IntelliJ Amiya
通过从片段调用updatelist(list)解决了这个问题。 - malli
8个回答

5
最后,在从Volley库获取API响应后,从Fragment类中调用此方法才能使其工作。
我在ViewModel类中编写了以下方法。
public void updateList(ArrayList<Class> list){
        if(adapter != null) {
            adapter.updateList(list);
        }
    }

然后像下面这样从片段类中调用此方法。

ArrayList<StatisticsModel> list = (ArrayList) data;
        viewModel.updateList(list);

所以在适配器类更新方法中,如下所示。
public void updateList(ArrayList<StatisticsModel> itemList){
        list.clear();
//        this.list = itemList;
//        list.addAll(itemList);
//        notifyItemInserted(list.size());
//        notifyDataSetChanged();
        this.list.addAll(itemList);
//        notifyItemInserted(list.size());
        notifyDataSetChanged();
    }

1
不要。
 public void updateList(ArrayList<ItemModel> itemList)
        {
            list.clear();
            this.list = itemList;
            notifyDataSetChanged();
        }
  • 每次调用方法list.clear();都会清除所有值。

clear()方法用于从列表中删除所有元素。

注意:保留HTML标签。

 public void updateList(ArrayList<ItemModel> itemList)
            {
               this.list.addAll(itemList);
               notifyDataSetChanged();
            }

@mali this.list.addAll(itemList); - IntelliJ Amiya
对于测试用例@malli,移除if(adapter == null) {条件并设置getAdapter().notifyDataSetChanged(); - IntelliJ Amiya
@malli 我猜你的 IF 代码块出了问题。 - IntelliJ Amiya
2
当我注释掉那个方法后,适配器每次初始化都能正常工作并按预期工作,但我不想每次都这样做,我正在持续更新。 - malli
@mali 调用此处的 onResume() 部分。 - IntelliJ Amiya
显示剩余2条评论

1

我也遇到了同样的问题,你在这里犯了一个错误,需要将list更改为itemList:

    @Override
    public int getItemCount() {
        return itemList.size();
    }

1
尝试这个。
    getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                       view.adapter.notifyDataSetChanged();
                }
            });

0

尝试从您的updateList方法中删除list.clear();

public void updateList(ArrayList<ItemModel> itemList){

            this.list.addAll(itemList);
            notifyItemInserted(list.size());
            notifyDataSetChanged();
        }

notifyItemInserted(int position)

通知所有已注册的观察者,位于特定位置的项已经被插入。

还可以尝试这个:

        list.addAll(your new list);

        if (adapter == null) {
            view.setHasFixedSize(true);
            mLayoutManager = new LinearLayoutManager(fragment.getContext());
            view.setLayoutManager(mLayoutManager);
            adapter = new TasksAdapter(fragment, fragment.getContext(), list);
            view.setAdapter(adapter);
            view.addItemDecoration(new DividerItemDecoration(fragment.getContext()));
        } else {


            view.notifyItemInserted(list.size());
            view.notifyDataSetChanged();
        }

@malli 试试这个 notifyItemInserted(list.size()); - AskNilesh
@malli 尝试在从片段调用 adapter.updateList(list); 后使用 adapter.notifyDataSetChanged(); - AskNilesh
我已经尝试过了,你可以在帖子中看到那段被注释的代码。 - malli
我们在聊天中继续这个讨论。 - AskNilesh

0
尝试在您的Fragment类中添加notifyDataSetChanged(),例如...
adapter.notifyDataSetChanged();

1
是的,我也尝试过这个,但没有成功,你可以看到我在代码中注释了那一行。 - malli

0

我不知道为什么有时候我们没有创建两个适配器实例,而且我们在主线程上调用adapter.notifyDataSetChanged()方法也不起作用。在这种情况下,只需从Adapter类中调用notifyDataSetChanged()方法即可。

adapter.setNewValue(newlist)

并且在AdapterClass上

fun setNewValue(newlist:ArrayList<Any>) {
list = newlist
notifyDataSetChanged()  
} 

0

我有同样的问题。在我的情况下,logcat中出现了错误消息: RecyclerView:未附加布局管理器;跳过布局

我使用以下代码修复了这个问题

    LinearLayoutManager llm = new LinearLayoutManager(this.getActivity());
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    mRecyclerView.setLayoutManager(llm);

然后调用 notifyDataSetChanged 方法开始工作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接