Android完美解决ListView复用导致的Checkbox状态混乱问题

在Android开发中,ListView、RecyclerView和GridView控件是实现列表布局的不可或缺的工具,我觉得暂且可以这么说。比如QQ好友列表等,我们不可能用循环的方式去实现,这样对应用的性能也是有很大影响的。所以,为了记录之前遇到的这个问题,也顺便给其他需要解决这个问题的童鞋看一下,写了这篇文章(大神勿喷)!

当然,如果你的布局比较简单,你说我没必要复用,那么你看到这里可以return了....

如果想用但是不知道怎么用的呢(基本不存在吧),可以参考下之前刚接触Android时写的一篇博客------ Android ListView的复用优化 那么言归正传,如果你搜到这篇文章,那么你遇到的问题应该是下面这样的:

我们实现CheckBox的选中效果一般有两种:

  • 设置CheckBox的setOnClickListener()监听
  • 设置CheckBox的setOnCheckedChangeListener()监听 下面针对这两种实现,提出两种解决方案:
1. 通过setOnClickListener()监听实现

传递给适配器的数据的实体类中添加一个是否选中的自选,比如我demo中这个,除了文本信息和图片信息外,我增加一个hasChecked属性来标记该item是否被选中,实体类信息如下:

private String description; //文字描述
private int resId; //图片id
private boolean hasChecked; //是否选中
复制代码

然后我们在Listview的Adapter适配器中去实现监听效果:

mCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // checkbox控件的方法,判断控件是否选中
                if(mCheckBox.isChecked()){
                    //自己在实体类中实现的方法 对属性就行赋值 标记是否选中
                    mData.get(position).setHasChecked(true);
                    //计数 为了便于观察 与此问题解决无关
                    selectCount++;
                }else {
                    mData.get(position).setHasChecked(true);
                    selectCount--;
                }
              }
        });
复制代码

看到这里,你估计要说,我也是这么写的啊,为什么我的不行呢?莫慌,仔细考虑一下,之所以发生混乱是因为没有对每个item的Checkbox赋初始值,导致布局控件复用的时候,还是会使用复用到的控件的值。 所以,我们只需要在设置setOnClickListener()监听之前,为item的checkbox赋一个初始值即可解决该问题。

mCheckBox.setChecked(mData.get(position).isHasChecked());
复制代码
2. 通过setOnCheckedChangeListener()监听实现

使用该方法实现和通过方法1实现有一个共同点就是都需要给item赋一个初始值,但是不一样的地方是,如果你debug代码你可以发现,滚动的时候,你不需要点击checkbox它就会自动调用onCheckChanged()方法,然后去执行里面的逻辑,问题依旧没有解决!

这时候,我们只需要在设置初始值之前给checkbox取消setOnCheckedChangeListener()监听就可以解决这个问题!

mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setChecked(mData.get(position).isHasChecked());
mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked){
                    mData.get(position).setHasChecked(true);
                    selectCount++;
                }else {
                    mData.get(position).setHasChecked(false);
                    selectCount--;
                }
              }
        });
复制代码

然后可以看一下效果就是这样式滴:

好了,到这里两种方法就讲完了,聪明的你是不是觉得炒鸡简单呢? 如果对你有用的话,可以点个喜欢哦,谢谢(手动比心)

如果你有其他的方法欢迎同我这只菜鸟交流哦! CSDN博客传送门---点击进入骑蜗牛去看大海的CSDN博客主页 点我可以下载demo的源码哦

转载于:https://juejin.im/post/5a31cf255188256e174e1738

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值