Recyclerview删除或者插入数据需要同步刷新列表一般会用到
notifyDataSetChanged();
notifyItemInserted(position)
notifyItemRemoved(position)
当使用
notifyItemInserted(position)
notifyItemRemoved(position)
会导致ViewHolder的position出现错误,比如有五条数据,当你删掉第二条,那么你理所当然以为后面的条目position会往前跳变成123(position由0开始),然而事实并不是,上面两条代码只是局部刷新,其他的ViewHolder并不会更新
当然解决方法很简单,使用notifyDataSetChanged();或者其他类似notifyItemRangeInserted();这种范围性刷新的就行,但是这些方法会导致Recyclerview闪烁,不想闪烁就只能关闭动画。
当然如果有想要动画,又要解决问题,可以尝试我以下的方法:
创建一个bean类,该bean类用来储存每个Viewholder显示的数据
private class ViewHolderBean{
public String shuju;
public String shuju2;
public int positon;
//constructor
//getter and setter
}
注意到有一个position变量,用来标识数据和选中viewholder的position对应关系
然后通过一个List来管理这些bean
private ArrayList<ViewHolderBean> itemViews = new ArrayList<>();
每次绑定ViewHolder的时候向列表添加新数据
@Override
public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
itemViews.add(new ViewHolderBean(你的数据...,position));
}
具体使用就是当要插入数据或者删除数据时找出列表里面bean的position与点击的Viewholder的position的条目再用bean里面的内容进行操作
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (ViewHolderBean bean: itemViews) {
if (bean.getPosition() == position) {
data.remove(bean.getdata());
notifyItemRemoved(holder.getLayoutPosition());
}
}
}
});
注意到这行:
notifyItemRemoved(holder.getLayoutPosition());
虽然viewholder的position不会刷新,但是recyclerview的item数量还是减少了的,所以我们移除的应该是viewholder在列表中的位置
???
等等,holder.getLayoutPosition()不是能获得准确的position吗
所以以上都是废话,真正解决办法是使用holder.getLayoutPosition()代替position
同时,因为holder.getLayoutPosition()会变化,所以不要设置为局部变量使用:
val layoutPosition = holder.getLayoutPosition()
可能有点问题,如果条目特别多效果不是很好
如果有什么更好的办法可以分享一下