解决listview嵌套checkbox滑动时状态的错乱

本文介绍如何正确处理 ListView 中 CheckBox 的复用问题,避免选中状态错乱,并提供了解决方案及实现点击 item 切换 CheckBox 状态的方法。

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

在listview的item中存在CheckBox时也会由于复用convert view导致CheckBox的选中状态错乱,本片内容将解决由于复用导致CheckBox选中状态错乱的问题。

先看下存在问题的效果图
这里写图片描述


public class MainActivity extends AppCompatActivity {
    private ListView mListView;
    private List<String> mStringList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStringList=new ArrayList<>();
        mStringList.add("北京市");mStringList.add("天津市");mStringList.add("上海市");mStringList.add("重庆市");
        mStringList.add("河北省");mStringList.add("山西省");mStringList.add("辽宁省");mStringList.add("河南省");
        mStringList.add("山东省");mStringList.add("湖北省");mStringList.add("湖南省");mStringList.add("江西省");
        mStringList.add("福建省");mStringList.add("陕西省");mStringList.add("四川省");mStringList.add("台湾省");
        mListView= (ListView) findViewById(R.id.lv_main);
        MyAdapter adapter=new MyAdapter(this,mStringList);
        mListView.setAdapter(adapter);

    }
}

public class MyAdapter extends BaseAdapter {

    List<String> mStringList;
    Context mContext;
    private Map<Integer,Boolean> map=new HashMap<>();// 存放已被选中的CheckBox

    public MyAdapter(Context context, List<String> stringList) {
        mStringList = stringList;
        mContext=context;
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
          MyViewHolder holder;
        if(convertView==null){
            convertView=View.inflate(mContext,R.layout.item,null);
            holder=new MyViewHolder();
            holder.mTextView= (TextView) convertView.findViewById(R.id.tv_item);
            holder.mCheckBox= (CheckBox) convertView.findViewById(R.id.cb_item);
            convertView.setTag(holder);
        }else {
            holder= (MyViewHolder) convertView.getTag();
        }

        holder.mTextView.setText(mStringList.get(position));
        holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked==true){
                    map.put(position,true);
                }else {
                    map.remove(position);
                }
            }
        });
      if(map!=null&&map.containsKey(position)){
            holder.mCheckBox.setChecked(true);
        }else {
            holder.mCheckBox.setChecked(false);
        }

        return convertView;
    }

    @Override
    public int getCount() {
        return mStringList.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    public static class  MyViewHolder {
        TextView mTextView;
        CheckBox mCheckBox;
    }
}

这样写就不会出现错乱问题了,但是现在大多数时候都是点击item 也能使checkbox选中,如果要实现这个功能的话,只需要给ListView设置监听时间
话不多说,直接上代码,很简单的两行代码。
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final CheckBox checkbox= (CheckBox) view.findViewById(R.id.checkbox); checkbox.setChecked(!checkbox.isChecked()); }});

listview与checkbox会有焦点的冲突,如果需要取消的子控件焦点太多,就可以直接给布局设置

descendantFocusability="blocksDescendants" 这个属性,

布局里面的所有子控件焦点都会取消,

单个取消的话设置

focusable="false"
就OK了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值