You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ListView点击首行RadioButton后滚动时其他行按钮误选中的解决方法

解决ListView中RadioButton选中状态滚动后混乱的问题

我在ListView的每个item里放置了3个RadioButton,点击首行的RadioButton后,向下滚动ListView时,发现其他行的RadioButton也会被莫名选中,具体情况如下:

【首行RadioButton被选中】
首行RadioButton被选中

【滚动后另一行RadioButton被选中】
另一行RadioButton也被选中

以下是我当前的适配器代码:

@Override 
public View getView(final int position, View convertView, final ViewGroup parent) { 
    final ViewHolder holder; 
    if (convertView == null) { 
        holder = new ViewHolder(); 
        convertView = inflater.inflate(R.layout.item_listview, null); 
        holder.tvAlat = (TextView) convertView.findViewById(R.id.tv_alat); 
        holder.tvpengecekan = (TextView) convertView.findViewById(R.id.tv_pengecekan); 
        holder.tvnormal = (TextView) convertView.findViewById(R.id.tv_normal); 
        convertView.setTag(mPengecekanList.get(position).getId_pengecekan()); 
        holder.baik = (RadioButton) convertView.findViewById(R.id.B); 
        holder.rusakringan = (RadioButton) convertView.findViewById(R.id.RR); 
        holder.rusakberat = (RadioButton) convertView.findViewById(R.id.RB); 
        convertView.setTag(holder); 
    } else { 
        holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.tvAlat.setText(mPengecekanList.get(position).getNama_alat()); 
    holder.tvpengecekan.setText(mPengecekanList.get(position).getPengecekan()); 
    holder.tvnormal.setText(mPengecekanList.get(position).getNormal()); 
    holder.baik.setTag(position); 
    holder.rusakringan.setTag(position); 
    holder.rusakberat.setTag(position); 
    holder.baik.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "1"); 
        }
    }); 
    holder.rusakringan.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "2"); 
        }
    }); 
    holder.rusakberat.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "3"); 
        }
    });
}

问题原因

这是ListView的视图复用机制在搞鬼!ListView为了提升性能,会重复使用已经滑出屏幕的item视图(也就是convertView)。你现在只在点击RadioButton时把选中状态存到了selectedAnswers集合里,但没有在每次复用视图时,根据集合里的真实状态去更新RadioButton的选中状态,所以旧视图里的选中状态就被带到了新的item上。

解决步骤

  1. 在getView方法末尾添加状态刷新逻辑:每次渲染item时,根据selectedAnswers里保存的值,手动设置对应RadioButton的选中状态,覆盖复用视图的旧状态。
  2. 修复ViewHolder的tag冲突问题:你之前在convertView为null时先设置了id为tag,之后又把holder设为tag,这会覆盖之前的tag,建议把id字段放到ViewHolder里。
  3. 补上getView的返回值:你原来的代码漏掉了返回convertView,这也会导致视图渲染异常。

修改后的完整代码片段

// 先给ViewHolder添加id字段
static class ViewHolder {
    TextView tvAlat;
    TextView tvpengecekan;
    TextView tvnormal;
    RadioButton baik;
    RadioButton rusakringan;
    RadioButton rusakberat;
    String idPengecekan; // 新增字段存储id
}

@Override 
public View getView(final int position, View convertView, final ViewGroup parent) { 
    final ViewHolder holder; 
    if (convertView == null) { 
        holder = new ViewHolder(); 
        convertView = inflater.inflate(R.layout.item_listview, null); 
        holder.tvAlat = (TextView) convertView.findViewById(R.id.tv_alat); 
        holder.tvpengecekan = (TextView) convertView.findViewById(R.id.tv_pengecekan); 
        holder.tvnormal = (TextView) convertView.findViewById(R.id.tv_normal); 
        holder.baik = (RadioButton) convertView.findViewById(R.id.B); 
        holder.rusakringan = (RadioButton) convertView.findViewById(R.id.RR); 
        holder.rusakberat = (RadioButton) convertView.findViewById(R.id.RB); 
        // 把id存到ViewHolder里,不再单独设置tag
        holder.idPengecekan = mPengecekanList.get(position).getId_pengecekan();
        convertView.setTag(holder); 
    } else { 
        holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.tvAlat.setText(mPengecekanList.get(position).getNama_alat()); 
    holder.tvpengecekan.setText(mPengecekanList.get(position).getPengecekan()); 
    holder.tvnormal.setText(mPengecekanList.get(position).getNormal()); 
    holder.baik.setTag(position); 
    holder.rusakringan.setTag(position); 
    holder.rusakberat.setTag(position); 
    holder.baik.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "1"); 
        }
    }); 
    holder.rusakringan.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "2"); 
        }
    }); 
    holder.rusakberat.setOnClickListener(new View.OnClickListener(){ 
        @Override public void onClick(View v) { 
            selectedAnswers.set(position, "3"); 
        }
    });

    // 关键:根据保存的状态刷新RadioButton
    String currentAnswer = selectedAnswers.get(position);
    if (currentAnswer != null) {
        holder.baik.setChecked("1".equals(currentAnswer));
        holder.rusakringan.setChecked("2".equals(currentAnswer));
        holder.rusakberat.setChecked("3".equals(currentAnswer));
    } else {
        // 如果没有选中状态,默认都不选
        holder.baik.setChecked(false);
        holder.rusakringan.setChecked(false);
        holder.rusakberat.setChecked(false);
    }

    return convertView; // 补上返回值
}

这样修改后,每次复用视图时都会根据selectedAnswers里的真实数据刷新RadioButton状态,滚动时就不会出现选中状态混乱的问题了。

内容的提问来源于stack exchange,提问作者Ibg Teguh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:44:00