使用View Binding时RecyclerView调用notifyItemRemoved删除条目异常如何解决
问题修复方案
核心错误原因
- 全局共用
ViewBinding实例:你将ItemPlayBinding定义为Adapter的全局成员,每次调用onCreateViewHolder都会覆盖该实例,所有条目最终只会指向最后创建的视图实例,导致绑定数据、设置点击事件全部串位。 - 点击事件使用固定位置参数:
onBindViewHolder传入的位置参数是绑定瞬间的静态值,条目删除后后续条目位置会动态变化,但旧点击事件里存储的还是历史位置,就会出现删错、点击无响应的问题。 - 缺失范围更新通知:删除条目后仅调用
notifyItemRemoved只会通知该位置移除,不会更新后续条目的位置索引,也是错位的诱因之一。
修正后的Adapter代码
public class AdapterPlay extends RecyclerView.Adapter<AdapterPlay.PlayerViewHolder> { // ViewBinding放到ViewHolder中持有,每个ViewHolder单独持有自己的绑定实例 public static class PlayerViewHolder extends RecyclerView.ViewHolder { ItemPlayBinding binding; PlayerViewHolder(ItemPlayBinding binding) { super(binding.getRoot()); this.binding = binding; } } private Activity mActivity; private List<ModelPlayers> modelPlayers = new ArrayList<>(); public AdapterPlay(Activity activity, List<ModelPlayers> modelPlayers) { this.mActivity=activity; this.modelPlayers = modelPlayers; } @Override public PlayerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { // 每个ViewHolder单独创建自己的Binding实例 ItemPlayBinding binding = ItemPlayBinding.inflate(LayoutInflater.from(mActivity),viewGroup,false); return new PlayerViewHolder(binding); } @Override public void onBindViewHolder(PlayerViewHolder holder, int position) { ModelPlayers modelPlayer = this.modelPlayers.get(position); // 用当前ViewHolder自己的binding设置数据 holder.binding.mainImage.setImageResource(modelPlayer.getImage()); holder.binding.mainText.setText(modelPlayer.getTitle()); holder.binding.mainText.setOnClickListener(v -> { // 点击时拿实时的adapter位置,不要用固定的position参数 int curPos = holder.getAdapterPosition(); // 做合法性校验,避免位置无效时报错 if (curPos != RecyclerView.NO_POSITION) { modelPlayers.remove(curPos); notifyItemRemoved(curPos); // 通知后续条目位置更新,修正索引 notifyItemRangeChanged(curPos, modelPlayers.size()); } }); } @Override public int getItemCount() { return modelPlayers.size(); } }
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

