解决RecycleView的holder复用而导致checkbox乱选的问题

本文介绍了一种解决RecyclerView中Checkbox因ViewHolder复用导致的选择错乱问题的方法。通过禁用复用或使用List记录每个Item的状态,确保了CheckBox状态的一致性和准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先来看一下BUG的效果
这里写图片描述
从上面可以看到当我点击了第一个Item的checkbox的时候,滚到下面的时候有一个也同时被点击了,这是由于holder的服用导致的Bug。
解决方法有两个:
①、直接设置recycleAdapter禁止复用

  viewHolder.setIsRecyclable(false);

当然啦,当数据特别多的时候,这个方法是不可行的,这会导致OOM

②、用一个List来记录每个Item的状态
先贴代码

   //解决holder复用问题
   private List<Integer> favorList=new ArrayList<>();

这里用一个List来保存每个Item的position,来唯一标识这个Item,当然啦,
得先给这个Item打上一个标签,这个是必须的,标识这个Item,以下代码在onBindViewHolder函数里面实现

   ((DisViewHolder) holder).favor.setTag(new Integer(position));

接着就是先判断,如果当前这个Item的tag是在List里面,那就代表着选中状态,否则就是未选中状态

     if(favorList.contains(((DisViewHolder) holder).favor.getTag()))
         ((DisViewHolder) holder).favor.setChecked(true);
     else 
         ((DisViewHolder) holder).favor.setChecked(false);

最后,在favor这个checkbox的setOnCheckedChangeListener监听方法里面如下操作

((DisViewHolder)holder).favor.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    if (isChecked){
                        if(!favorList.contains(((DisViewHolder) holder).favor.getTag())){
                            favorList.add(new Integer(position));
                        }
                    }else{
                        if(favorList.contains(((DisViewHolder) holder).favor.getTag())){
                            favorList.remove(new Integer(position));
                        }
                    }
                }
            });

很明显,当点击checkbox的时候,在ischecked里面的两个if是判断当前的Item是否已经在List里面了,如果在的话那就remove掉,如果不在就add进来。

接着看一下效果
这里写图片描述

checkbox选择不再错乱了。

至此,文章结束,希望能帮助到有需要的朋友,谢谢。

RecyclerView 的复用机制是为了优化性能而设计的,它会复用已经创建的 View,来减少创建新 View 的次数,从而提高滑动的流畅度。在 RecyclerView 中,每当一个 item 滑出屏幕时,其对应的 View 会被回收,并放入到一个 ViewPool 中,以供后续使用。在需要新的 item 时,先从 ViewPool 中获取一个可用的 View,然后通过 onBindViewHolder() 方法将数据绑定到这个 View 上。 但是,这个复用机制也会带来一些问题,比如当 item 的布局和内容变化很大时,可能会出现数据重叠、错乱问题。这是因为 RecyclerView 在复用 View 的过程中,没有清空之前 View 的状态,导致新的数据与之前的数据混合在一起。 为了解决这个问题,可以采用以下两种方法: 1. 在 onBindViewHolder() 方法中,清空之前 View 的状态。这样可以确保每次绑定新数据时,View 的状态都是干净的。比如,可以将需要清空的状态设置为默认值,或者使用 View.setTag() 方法保存状态,在下次使用时再根据 Tag 进行清空。 2. 使用不同的 ViewType。如果 item 的布局和内容变化很大,可以根据数据的类型,设置不同的 ViewType。这样就可以确保每个 View 只会被用于一种类型的数据,避免数据重叠、错乱问题。在 onCreateViewHolder() 方法中,可以根据 ViewType 创建不同的 View。 总之,复用机制是 RecyclerView 的重要特性,可以优化滑动的性能。但是在使用时,需要注意清空之前 View 的状态,或者使用不同的 ViewType 来避免数据重叠、错乱问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值