ListView中嵌套CheckBox选中状态错乱的解决方案

实现CheckBox的选中状态,一般有两种实现方法:

1、设置CheckBox的setOnCheckedChangeListener()监听

2、设置CheckBox的setOnClickListener()监听

针对这两种实现方法,下面提供两种解决方案:

一、通过CheckBox的setOnCheckedChangeListener()监听来实现

首先定义一个实体类,该实体类除了定义你需要的信息,然后再增加一个是否选中的属性,以便于后续记录该条数据的选中状态。

public class ProductInfo {
    private String productNo;
    private String productName;
    private boolean checked;

    public String getProductNo() {
        return productNo;
    }

    public void setProductNo(String productNo) {
        this.productNo = productNo;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
    }
}

其次我们在适配器中实现监听功能。

public class ProductAdapter extends BaseAdapter {
    private Context mContext;
    private List<ProductInfo> mProductInfoList;

    public ProductAdapter(Context context, List<ProductInfo> productInfoList) {
        this.mContext = context;
        this.mProductInfoList = productInfoList;
    }

    @Override
    public int getCount() {
        return mProductInfoList != null ? mProductInfoList.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return mProductInfoList != null ? mProductInfoList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHoder viewHoder;
        if (convertView != null) {
            viewHoder = (ViewHoder) convertView.getTag();
        } else {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_product_list_item, null);

            viewHoder = new ViewHoder();
            viewHoder.checkBox = convertView.findViewById(R.id.checkbox);
            viewHoder.tvProductNo = convertView.findViewById(R.id.tv_product_no);
            viewHoder.tvProductName = convertView.findViewById(R.id.tv_product_name);

            convertView.setTag(viewHoder);
        }

        // 因为ListView滑动的时候,会自动调用onCheckedChanged方法,因此这里先设置位null,待设置为选中状态以后,再次设定CheckBox的监听
        viewHoder.checkBox.setOnCheckedChangeListener(null);
        viewHoder.checkBox.setChecked(mProductInfoList.get(position).isChecked());
        viewHoder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mProductInfoList.get(position).setChecked(true);
                } else {
                    mProductInfoList.get(position).setChecked(false);
                }
            }
        });

        String productNo = mProductInfoList.get(position).getProductNo();
        String productName = mProductInfoList.get(position).getProductName();
        viewHoder.tvProductNo.setText(productNo);
        viewHoder.tvProductName.setText(productName);

        return convertView;
    }

    final class ViewHoder {
        public CheckBox checkBox;
        public TextView tvProductNo, tvProductName;
    }
}

注意:ListView在滚动的时候,你不需要点击CheckBox它就会自动调用onCheckChanged()方法,因此我们需要在设置初始值之前给CheckBox取消setOnCheckedChangeListener()监听,初始值设置完成之后,再次增加监听方法。

二、通过CheckBox的setOnClickListener()监听来实现

实体类不变,对上面的代码我们只要稍加改动就好了,具体代码如下。

public class ProductAdapter extends BaseAdapter {
    private Context mContext;
    private List<ProductInfo> mProductInfoList;

    public ProductAdapter(Context context, List<ProductInfo> productInfoList) {
        this.mContext = context;
        this.mProductInfoList = productInfoList;
    }

    @Override
    public int getCount() {
        return mProductInfoList != null ? mProductInfoList.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return mProductInfoList != null ? mProductInfoList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHoder viewHoder;
        if (convertView != null) {
            viewHoder = (ViewHoder) convertView.getTag();
        } else {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_product_list_item, null);

            viewHoder = new ViewHoder();
            viewHoder.checkBox = convertView.findViewById(R.id.checkbox);
            viewHoder.tvProductNo = convertView.findViewById(R.id.tv_product_no);
            viewHoder.tvProductName = convertView.findViewById(R.id.tv_product_name);

            convertView.setTag(viewHoder);
        }

        final CheckBox ck = viewHoder.checkBox;
        viewHoder.checkBox.setChecked(mProductInfoList.get(position).isChecked());
        viewHoder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ck.isChecked()) {
                    mProductInfoList.get(position).setChecked(true);
                } else {
                    mProductInfoList.get(position).setChecked(false);
                }
            }
        });

        String productNo = mProductInfoList.get(position).getProductNo();
        String productName = mProductInfoList.get(position).getProductName();
        viewHoder.tvProductNo.setText(productNo);
        viewHoder.tvProductName.setText(productName);

        return convertView;
    }

    final class ViewHoder {
        public CheckBox checkBox;
        public TextView tvProductNo, tvProductName;
    }
}

通过以上两种方案,就可以实现选择不出现错乱的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值