RecyclerView Checkbox状态异常求助:滚动后取消选中/自动选中其他项
RecyclerView搭配Checkbox选中状态异常问题解决
问题描述
- 向下滚动页面后再向上滚动,Checkbox自动取消选中
- 勾选某一项时,页面下方的其他项自动被勾选
问题原因分析
你的代码同时用了itemStateArray和TasModel的checked字段维护选中状态,但两者完全没有同步:
bind方法仅读取itemStateArray设置Checkbox状态,完全忽略TasModel的checked值onClick方法仅修改TasModel的checked字段,未更新itemStateArray- RecyclerView的复用机制会将旧ViewHolder重新绑定到新位置,状态不同步就导致错乱
修复方案
统一用TasModel的checked字段维护状态(符合数据驱动UI的设计思想),修改后的代码如下:
修改后的Adapter代码
private Context mCtx; private List<TasModel> tasList; Tasadapter() { } public Tasadapter(Context mCtx, List<TasModel> tasList) { this.mCtx = mCtx; this.tasList = tasList; } @NonNull @Override public TasviewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { LayoutInflater inflater = LayoutInflater.from(mCtx); View view = inflater.inflate(R.layout.tas_list, null); TasviewHolder holder = new TasviewHolder(view); return holder; } @Override public void onBindViewHolder(@NonNull final TasviewHolder tasviewHolder, int position) { tasviewHolder.bind(position); } @Override public int getItemCount() { return tasList.size(); } class TasviewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ TextView name, roll; CheckBox checkBox; public TasviewHolder(@NonNull View itemView) { super(itemView); name = itemView.findViewById(R.id.tasName); roll = itemView.findViewById(R.id.tasRoll); checkBox = itemView.findViewById(R.id.tasBox); itemView.setOnClickListener(this); // 单独给Checkbox设置点击监听,避免与item点击事件冲突 checkBox.setOnClickListener(v -> { int pos = getAdapterPosition(); tasList.get(pos).setChecked(checkBox.isChecked()); }); } void bind(int position) { TasModel tasModel = tasList.get(position); // 直接从Model读取选中状态,确保复用ViewHolder时状态正确 checkBox.setChecked(tasModel.getChecked()); checkBox.setText(String.valueOf(tasModel.getPosition())); name.setText(tasModel.getName()); roll.setText(tasModel.getRoll()); } @Override public void onClick(View v) { int adapterPosition = getAdapterPosition(); TasModel model = tasList.get(adapterPosition); // 点击item时切换选中状态,同步更新Model和UI boolean newState = !model.getChecked(); model.setChecked(newState); checkBox.setChecked(newState); } }
关键修改点
- 移除了多余的
itemStateArray,统一用TasModel的checked字段维护状态 - 给Checkbox单独设置点击监听,避免item点击与Checkbox原生点击事件冲突
bind方法直接从Model读取状态,确保复用ViewHolder时显示正确的选中状态- 点击item和Checkbox时,同步更新Model状态与Checkbox UI
额外建议
- 不要调用
setIsRecyclable(false),这会禁用RecyclerView的复用机制,导致性能下降 - 如需批量操作选中项,直接遍历
tasList筛选getChecked()为true的元素即可
内容的提问来源于stack exchange,提问作者Royhan Sajib
相关产品推荐
相关产品推荐

