【问题标题】:recyclerview notifyDataSetChanged() is not workingrecyclerview notifyDataSetChanged() 不工作
【发布时间】:2017-10-30 06:33:15
【问题描述】:

我正在尝试使用 updateList() 中的 notifyDataSetchanged() 更新 myadapter。但不适用于 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();
            }
        }

请检查一下,让我知道我在哪里做错了。提前谢谢..

【问题讨论】:

  • 为什么 list.clear();updateList(list);
  • 它只是用于删除列表中分配的先前数据。
  • 去掉这一行 view.setHasFixedSize(true);否则让它为假。
  • 感谢@mehul 的回复,但没有运气
  • @malli 解决了这个问题了吗?

标签: java android android-recyclerview notifydatasetchanged


【解决方案1】:

一旦从 volley 库中获得 API 响应,最终通过从片段类调用此方法来工作。

我在 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();
    }

【讨论】:

    【解决方案2】:

    不要

     public void updateList(ArrayList<ItemModel> itemList)
            {
                list.clear();
                this.list = itemList;
                notifyDataSetChanged();
            }
    
    • 每当调用此方法时list.clear();清除所有值。

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

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

    【讨论】:

    • @malli this.list .addAll(itemList);
    • @malli 用于测试用例删除if(adapter == null) { 条件并设置getAdapter().notifyDataSetChanged();
    • @malli 我猜你的 IF 块创建问题
    • 它涉及到 else 语句并且可以在适配器类 updateList() 中进行调试,但列表没有刷新它显示为空
    • 当我评论该方法每次适配器初始化时都能正常工作并按预期工作,但我不想每次都这样做,我会不断更新
    【解决方案3】:

    我也遇到了同样的问题,你做错了,把list改成itemList:

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

    【讨论】:

      【解决方案4】:

      试试这个

          getActivity().runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                             view.adapter.notifyDataSetChanged();
                      }
                  });
      

      【讨论】:

        【解决方案5】:

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

        adapter.notifyDataSetChanged();
        

        【讨论】:

        • 是的,我也试过这个,但没有运气,你可以看到我在我的代码中评论了那行..
        【解决方案6】:

        尝试从您的 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());
        • @malli 在从片段中调用 adapter.updateList(list); 后试试这个 adapter.notifyDataSetChanged();
        • 我已经试过了,你可以看到帖子中注释的代码。
        【解决方案7】:

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

        我已经用下面的代码修复了

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

        然后 notifyDataSetChanged 开始工作

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-05
          • 2023-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-27
          • 1970-01-01
          • 2014-09-04
          相关资源
          最近更新 更多