RecyclerView关于notifyItemRemoved的那点小事
RecyclerView很多时候是展示静态的数据,并不会有删除的操作,讲到RecyclerView时,会提到它提供了一个很好的展现删除操作动画的函数,代码片段一般是这样的:
@Override
public void onBindViewHolder(final CommonViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDataList.remove(position);
notifyItemRemoved(position);
}
});
}
这样写的话,很快会产生数据删除错乱和超出索引异常导致崩溃。
原因是函数里面的传入的参数position,它是在进行onBind操作时确定的,在删除单项后,已经出现在画面里的项不会再有调用onBind机会,这样它保留的position一直是未进行删除操作前的postion值。
解决办法也很简单 :
//或者使用holder.getAbsoluteAdapterPosition()
mDataList.remove(holder.getBindingAdapterPosition());
notifyItemRemoved(holder.getBindingAdapterPosition());
请注意,如果您要查询RecyclerView所看到的位置,则应使用getAbsoluteAdapterPosition()(例如,要使用它来保存滚动状态)。如果要查询访问RecyclerView.Adapter内容的位置,则应使用getBindingAdapterPosition()。
或者下面的方法也行:
public void remove(int position) {
mDataList.remove(position);
notifyItemRemoved(position);
if(position != mDataList.size()){ // 如果移除的是最后一个,忽略
notifyItemRangeChanged(position, mDataList.size() - position);
}
}
参考:
RecyclerView里notifyItemRemoved的坑
不推荐使用getAdapterPosition()(getAdapterPosition() is deprecated)