[英]How to use RecyclerView.Adapter notifyItemInserted/Removed in a right way?
For instance, you have an adapter and in onBindViewHolder method you set OnClickListener to some views (and do some actions there depending on view position).例如,您有一个适配器,并在 onBindViewHolder 方法中将 OnClickListener 设置为某些视图(并根据视图位置在那里执行一些操作)。 You should assign final
to position param of method onBindViewHolder so it could be accessible from onClick().您应该将final
分配给方法 onBindViewHolder 的 position 参数,以便可以从 onClick() 访问它。
After changing dataset (remove or add item in list) you call onItemInserted or onItemRemoved and this really adds/removes a view in the recyclerview, BUT it does not refresh other viewitems so when you click on a neighbor viewitem it will open a screen or show data with invalid index.更改数据集(删除或添加列表中的项目)后,您调用 onItemInserted 或 onItemRemoved,这实际上在回收视图中添加/删除了一个视图,但它不会刷新其他视图,因此当您单击相邻视图时,它将打开一个屏幕或显示索引无效的数据。 To avoid this I basically call notifyDatasetChanged to call onBind to all visible views and remove/add some views.为了避免这种情况,我基本上调用 notifyDatasetChanged 来调用 onBind 到所有可见视图并删除/添加一些视图。
So how to refresh other views when you call notifyItemInserted/removed or how to work with these methots appropriately?那么如何在调用 notifyItemInserted/removed 时刷新其他视图,或者如何适当地使用这些方法?
Assigning the position to a variable in onBindViewHolder
will lead to an inconsistent state if items in the dataset are inserted or deleted without calling notifyDataSetChanged
. 如果插入或删除数据集中的项而不调用notifyDataSetChanged
, onBindViewHolder
位置分配给onBindViewHolder
的变量将导致不一致的状态。
To use onItemInserted
or onItemRemoved
the data in the viewholder should remain consistent since it will not be redrawn and onClick
would use this invalid position assigned before an item was added or removed. 要使用onItemInserted
或onItemRemoved
的数据应保持一致,因为它不会被重绘, onClick
会在添加或删除项目之前使用此无效位置。
For this and other use cases the RecyclerView.ViewHolder
provides methods to access its position and id: 对于此用例和其他用例, RecyclerView.ViewHolder
提供了访问其位置和id的方法:
Use getAdapterPosition()
or getItemId()
to get valid positions and ids. 使用getAdapterPosition()
或getItemId()
来获取有效位置和ID。
Also have a look on the other methods available in RecyclerView.ViewHolder
. 另请参阅RecyclerView.ViewHolder
提供的其他方法。
So, the way I fix the problem I had is by changing the position
into viewHolder.getAdapterPosition()
所以,我解决问题的方法是将position
更改为viewHolder.getAdapterPosition()
Cheers! 干杯!
I advise you to add notifyItemRangeChanged after insert or remove list inside adapter. 我建议你在插入或删除适配器内的列表后添加notifyItemRangeChanged。 This work for my project. 这项工作适用于我的项目。
Example in remove item : 删除项目中的示例:
public void removeItem (int pos) {
simpanList.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, simpanList.size());//add here, this can refresh position cmiiw
}
For future readers, this is what I do when inserting/removing in recyclerview For example, my model class is CarsModel
对于未来的读者,这就是我在 recyclerview 中插入/删除时所做的例如,我的 model class 是CarsModel
In my adapter在我的适配器中
ArrayList<CarsModel> carsModel;
In onBindViewHolder在 onBindViewHolder 中
CardModel model = carsModel.get(position);
When removing data in list using button in holder:使用持有人中的按钮删除列表中的数据时:
int position = holder.getAdapterPosition();
carsModel.remove(position);
notifyItemRemoved(position);
Then when inserting然后插入的时候
carsModel.add(0, model);
notifyItemInserted(0);
or insert in last row或插入最后一行
carsModel.add(carsModel.size() - 1 , model);
notifyItemInserted(carsModel.size()-1);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.