简体   繁体   English

如何正确使用 RecyclerView.Adapter notifyItemInserted/Removed?

[英]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 . 如果插入或删除数据集中的项而不调用notifyDataSetChangedonBindViewHolder位置分配给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. 要使用onItemInsertedonItemRemoved的数据应保持一致,因为它不会被重绘, 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.

相关问题 如何在Kotlin的RecyclerView.Adapter中使用SharedPreferences? - How to use SharedPreferences in RecyclerView.Adapter in Kotlin? 如何在 RecyclerView.Adapter 中使用 onActivityResult - How to use onActivityResult in RecyclerView.Adapter 如何在 RecyclerView.Adapter 中使用共享首选项? - How to use shared preferences in RecyclerView.Adapter? 如何在 RecyclerView.Adapter 中使用 ViewBinding? - How to use ViewBinding in a RecyclerView.Adapter? 对不同的RecyclerView使用相同的RecyclerView.Adapter吗? - Use same RecyclerView.Adapter for different RecyclerView? 如何在recyclerview(RecyclerView.Adapter)中删除边框? - How to remove the border in recyclerview (RecyclerView.Adapter)? 在 RecyclerView.Adapter 中实现 getItemId() 的正确方法 - The correct way of implementing getItemId() in RecyclerView.Adapter 如何使用 AsyncTask、RecyclerView 和 RecyclerView.Adapter 将手机中的图像获取到 RecyclerView? - How can I use AsyncTask, RecyclerView, and a RecyclerView.Adapter to get images from my phone into my RecyclerView? Kotlin:如何在 RecyclerView.Adapter 中调用 getSupportFragmentManager() - Kotlin: How to call getSupportFragmentManager() in RecyclerView.Adapter RecyclerView.Adapter StateRestorationPolicy 是如何工作的? - How RecyclerView.Adapter StateRestorationPolicy works?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM