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

Android中ListView自定义Adapter滚动时单选按钮状态不保存求助

解决ListView自定义Adapter单选按钮滚动后状态丢失的问题

嘿,这个问题我太熟悉了!本质是ListView的视图复用机制在搞鬼——当你滚动列表时,屏幕外的Item视图会被回收,用来显示新进入屏幕的Item,而你的Adapter没有在复用视图时正确恢复之前保存的选中状态,才导致状态丢失。下面是具体的修复方案:

问题根源分析

  • 你的getView方法只设置了单选按钮的监听器,但没有根据selectedAnswers里保存的值,给RadioButton设置正确的选中状态;
  • 视图复用时,旧的OnCheckedChangeListener会被保留,导致滚动时意外触发监听器,篡改selectedAnswers里的数据;
  • selectedAnswers被设为static,这会导致多个Adapter实例共享同一数据,容易引发状态混乱。

修复后的完整CustomAdapter代码

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.TextView;
import java.util.ArrayList;

public class CustomAdapter extends BaseAdapter {
    Context context;
    String[] questionsList;
    ArrayList<String> selectedAnswers; // 去掉static,避免多实例数据冲突
    LayoutInflater inflter;

    public CustomAdapter(Context applicationContext, String[] questionsList, ArrayList<String> array) {
        this.context = applicationContext;
        this.questionsList = questionsList;
        // 复制传入的初始数据,避免外部修改影响Adapter内部状态
        this.selectedAnswers = new ArrayList<>(array); 
        inflter = LayoutInflater.from(applicationContext);
    }

    @Override
    public int getCount() {
        return questionsList.length;
    }

    @Override
    public Object getItem(int i) {
        return questionsList[i];
    }

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

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {
        ViewHolder holder;
        // 使用ViewHolder模式优化视图复用性能,同时避免重复查找控件
        if (view == null) {
            view = inflter.inflate(R.layout.radio_group_item, viewGroup, false);
            holder = new ViewHolder();
            holder.question = view.findViewById(R.id.question);
            holder.yes = view.findViewById(R.id.yes);
            holder.no = view.findViewById(R.id.no);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        // 先移除旧监听器,避免复用视图时触发旧逻辑篡改数据
        holder.yes.setOnCheckedChangeListener(null);
        holder.no.setOnCheckedChangeListener(null);

        // 根据保存的状态,设置当前Item的单选按钮选中状态
        String currentAnswer = selectedAnswers.get(i);
        holder.yes.setChecked("Yes".equals(currentAnswer));
        holder.no.setChecked("No".equals(currentAnswer));

        // 重新设置监听器,处理用户选择逻辑
        holder.yes.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    selectedAnswers.set(i, "Yes");
                    // 同步取消另一个按钮的选中状态,避免同时选中
                    holder.no.setChecked(false);
                }
            }
        });

        holder.no.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    selectedAnswers.set(i, "No");
                    // 同步取消另一个按钮的选中状态
                    holder.yes.setChecked(false);
                }
            }
        });

        holder.question.setText(questionsList[i]);
        return view;
    }

    // ViewHolder内部类,缓存控件引用
    static class ViewHolder {
        TextView question;
        RadioButton yes;
        RadioButton no;
    }
}

额外优化建议

  • 在你的OnooltActivity2中,移除不必要的simpleList.onSaveInstanceState()和simpleList.onRestoreInstanceState()调用,因为Adapter已经通过selectedAnswers保存了状态;
  • 确保getDavaa()方法完成数据加载后,再初始化Adapter或者调用customAdapter.notifyDataSetChanged(),避免数据未加载完成就渲染视图;
  • 如果questions数组是动态加载的,记得在数据准备好后再赋值给Adapter,避免空指针异常。

这样修改后,ListView滚动时就能正确保存和恢复每个Item的单选按钮状态了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:36:31