如何更新RecyclerView适配器数据?

4天,我无法弄清楚什么是更新RecyclerView的适配器的问题。

我得到一个新的产品清单后,我试图:

  1. 从创buildrecyclerView的片段更新ArrayList ,将新数据设置为适配器,然后调用adapter.notifyDataSetChanged() ; 它不起作用。

  2. 创build一个新的适配器,像其他人一样,它为他们工作,但没有改变: recyclerView.setAdapter(new RecyclerViewAdapter(newArrayList))

  3. Adapter创build一个方法来更新数据,如下所示:

     public void updateData(ArrayList<ViewModel> viewModels) { items.clear(); items.addAll(viewModels); notifyDataSetChanged(); } 

    然后,每当我想更新数据列表时,我都会调用这个方法; 它不起作用。

  4. 要检查我是否可以以任何方式修改recyclerView,并试图删除至less一个项目:

      public void removeItem(int position) { items.remove(position); notifyItemRemoved(position); } 

    一切都保持原样。

这是我的适配器:

 public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements View.OnClickListener { private ArrayList<ViewModel> items; private OnItemClickListener onItemClickListener; public RecyclerViewAdapter(ArrayList<ViewModel> items) { this.items = items; } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false); v.setOnClickListener(this); return new ViewHolder(v); } public void updateData(ArrayList<ViewModel> viewModels) { items.clear(); items.addAll(viewModels); notifyDataSetChanged(); } public void addItem(int position, ViewModel viewModel) { items.add(position, viewModel); notifyItemInserted(position); } public void removeItem(int position) { items.remove(position); notifyItemRemoved(position); } @Override public void onBindViewHolder(ViewHolder holder, int position) { ViewModel item = items.get(position); holder.title.setText(item.getTitle()); Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image); holder.price.setText(item.getPrice()); holder.credit.setText(item.getCredit()); holder.description.setText(item.getDescription()); holder.itemView.setTag(item); } @Override public int getItemCount() { return items.size(); } @Override public void onClick(final View v) { // Give some time to the ripple to finish the effect if (onItemClickListener != null) { new Handler().postDelayed(new Runnable() { @Override public void run() { onItemClickListener.onItemClick(v, (ViewModel) v.getTag()); } }, 0); } } protected static class ViewHolder extends RecyclerView.ViewHolder { public ImageView image; public TextView price, credit, title, description; public ViewHolder(View itemView) { super(itemView); image = (ImageView) itemView.findViewById(R.id.image); price = (TextView) itemView.findViewById(R.id.price); credit = (TextView) itemView.findViewById(R.id.credit); title = (TextView) itemView.findViewById(R.id.title); description = (TextView) itemView.findViewById(R.id.description); } } public interface OnItemClickListener { void onItemClick(View view, ViewModel viewModel); } } 

我启动RecyclerView如下:

 recyclerView = (RecyclerView) view.findViewById(R.id.recycler); recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 5)); adapter = new RecyclerViewAdapter(items); adapter.setOnItemClickListener(this); recyclerView.setAdapter(adapter); 

那么,我该如何更新适配器数据才能显示新收到的项目呢?


更新:问题是gridView的布局看起来如下所示:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:tag="catalog_fragment" android:layout_height="match_parent"> <FrameLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false"/> <ImageButton android:id="@+id/fab" android:layout_gravity="top|end" style="@style/FabStyle"/> </FrameLayout> </LinearLayout> 

然后,我刚刚删除了LinearLayout ,并将FrameLayout作为父级布局。

我正在使用RecyclerView,删除和更新都很好。

1)删除:有一个步骤从RecyclerView中删除一个项目

 list.remove(position); recycler.removeViewAt(position); mAdapter.notifyItemRemoved(position); mAdapter.notifyItemRangeChanged(position, list.size()); 

这些代码行我工作。

2)更新数据:我唯一需要做的是

 mAdapter.notifyDataSetChanged(); 

您必须在Actvity / Fragment代码中执行所有这些操作,而不是在RecyclerView适配器代码中。

这对我来说是有效的:

 recyclerView.setAdapter(new RecyclerViewAdapter(newList)); recyclerView.invalidate(); 

创build一个包含更新列表的新适配器(在我的情况下,它是一个数据库转换成一个ArrayList),并设置为适配器,我试着recyclerView.invalidate() ,它的工作。

你有2个select来做到这一点:从适配器刷新UI:

 mAdapter.notifyDataSetChanged(); 

或者从recyclerView本身刷新它:

 recyclerView.invalidate(); 

我用不同的方式解决了同样的问题。 我没有数据,我从后台线程等待它,所以从一个emty列表开始。

  mAdapter = new ModelAdapter(getContext(),new ArrayList<Model>()); // then when i get data mAdapter.update(response.getModelList()); // and update is in my adapter public void update(ArrayList<Model> modelList){ adapterModelList.clear(); for (Product model: modelList) { adapterModelList.add(model); } mAdapter.notifyDataSetChanged(); } 

而已。

另一个select是使用diffutil 。 它会将原始列表与新列表进行比较,如果有更改,则使用新列表作为更新。

基本上,我们可以使用DiffUtil来比较旧数据和新数据,并以您的名义调用notifyItemRangeRemoved,notifyItemRangeChanged和notifyItemRangeInserted。

使用diffUtil代替notifyDataSetChanged的快速示例:

 DiffResult diffResult = DiffUtil .calculateDiff(new MyDiffUtilCB(getItems(), items)); //any clear up on memory here and then diffResult.dispatchUpdatesTo(this); 

如果它是一个大列表,我会在主线程中执行calclateDiff工作。

更新listview,gridview和recyclerview的数据

 mAdapter.notifyDataSetChanged(); 

要么

 mAdapter.notifyItemRangeChanged(0, itemList.size()); 

向当前数据添加新数据的最好和最酷的方法是

  ArrayList<String> newItems = new ArrayList<String>(); newItems = getList(); int oldListItemscount = alcontainerDetails.size(); alcontainerDetails.addAll(newItems); recyclerview.getAdapter().notifyItemChanged(oldListItemscount+1, al_containerDetails); 

我经过很长时间才得到答案

  SELECTEDROW.add(dt); notifyItemInserted(position); SELECTEDROW.remove(position); notifyItemRemoved(position); 

如果以上评论中没有提到任何内容为你工作。 这可能意味着问题在于别的地方。

我find解决scheme的一个地方就是我将这个列表设置到适配器上。 在我的活动中,这个列表是一个实例variables,当有任何数据改变时我直接改变它。 由于它是一个参考variables,有一些奇怪的事情。 所以我将引用variables改为本地variables,并使用另一个variables来更新数据,然后传递给上面答案中提到的addAll()函数。

我看到所有这些需要时间的方法,我find了一个方法。

我只是包含了一个Intent本身,并叫完成 ,这确保清单刷新。

 Intent intent = new Intent(context,thisActivity.class); startActivity(intent); finish(); 

完成!