Android RadioGroup在ListView中未正确保持状态

Android RadioGroup在ListView中未正确保持状态,android,listview,radio-group,Android,Listview,Radio Group,我知道ListView回收问题,并试图将我的状态保持在模型中,但它似乎不起作用。我读过许多关于同一问题的主题,但它们的解决方案对我不起作用,或者我做错了什么。 当我在radio group处于初始状态的情况下上下滚动列表视图时,什么也没发生,没错。但只要我在任何一行中设置checked,然后上下滚动,单选按钮就会被随机选中 RadioAdapter.java: public class RadioAdapter extends ArrayAdapter<Question> { Li

我知道ListView回收问题,并试图将我的状态保持在模型中,但它似乎不起作用。我读过许多关于同一问题的主题,但它们的解决方案对我不起作用,或者我做错了什么。 当我在radio group处于初始状态的情况下上下滚动列表视图时,什么也没发生,没错。但只要我在任何一行中设置checked,然后上下滚动,单选按钮就会被随机选中

RadioAdapter.java:

public class RadioAdapter extends ArrayAdapter<Question> {

List<Question> mSource;

static class ViewHolder {
    TextView category = null;
    TextView question = null;
    RadioGroup rbGroup = null;

    ViewHolder(View row) {
        this.category = (TextView) row.findViewById(R.id.tvQuestionCategory);
        this.question = (TextView) row.findViewById(R.id.tvQuestion);
        this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration);
    }
}

private LayoutInflater mInflater;

public RadioAdapter(Context context, List<Question> mSource) {
    super(context, R.layout.item_question, mSource);
    mInflater = LayoutInflater.from(context);
    this.mSource = mSource;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    View row = convertView;

    if (row == null) {
        row = mInflater.inflate(R.layout.item_question, null);

        holder = new ViewHolder(row);

        holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //Get position of current group
                Integer pos = (Integer) group.getTag();
                switch (checkedId) {
                    case R.id.rbIterationYes:
                        //Check 'YES' and uncheck 'NO'
                        mSource.get(pos).setYesChecked(true);
                        mSource.get(pos).setNoChecked(false);
                        break;

                    case R.id.rbIterationNo:
                        //Vice versa
                        mSource.get(pos).setNoChecked(true);
                        mSource.get(pos).setYesChecked(false);
                        break;
                }
            }
        });

        row.setTag(holder);
    } else {
        holder = (ViewHolder) row.getTag();
    }
    holder.rbGroup.setTag(new Integer(position));
    holder.category.setText(mSource.get(position).getCategory());
    holder.question.setText(mSource.get(position).getDescription());
    //If no one of buttons isn't checked
    if (!mSource.get(position).isYesChecked() && !mSource.get(position).isNoChecked()) {
        holder.rbGroup.clearCheck();
    }else {
        //We are supposing 'YES' is checked
        int c = 0;
        //Or 'NO' is checked
        if (mSource.get(position).isNoChecked()){
            c = 1;
        }
        //Set checked button
        ((RadioButton)holder.rbGroup.getChildAt(c)).setChecked(true);
    }
    return row;
}
public class Question {

     private Integer id;
     private String category;
     private String description;
     private boolean yesChecked;
     private boolean noChecked;

/* Getters and setters */
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:id="@+id/tvQuestionCategory"/>
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:id="@+id/tvQuestion"/>

<RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/rgIteration">
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:id="@+id/rbIterationYes"
            android:text="@string/rbIterationYes"
            android:textSize="16dp"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:id="@+id/rbIterationNo"
            android:text="@string/rbIterationNo"
            android:textSize="16dp" />
</RadioGroup>

</LinearLayout>
item\u question.xml:

public class RadioAdapter extends ArrayAdapter<Question> {

List<Question> mSource;

static class ViewHolder {
    TextView category = null;
    TextView question = null;
    RadioGroup rbGroup = null;

    ViewHolder(View row) {
        this.category = (TextView) row.findViewById(R.id.tvQuestionCategory);
        this.question = (TextView) row.findViewById(R.id.tvQuestion);
        this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration);
    }
}

private LayoutInflater mInflater;

public RadioAdapter(Context context, List<Question> mSource) {
    super(context, R.layout.item_question, mSource);
    mInflater = LayoutInflater.from(context);
    this.mSource = mSource;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    View row = convertView;

    if (row == null) {
        row = mInflater.inflate(R.layout.item_question, null);

        holder = new ViewHolder(row);

        holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //Get position of current group
                Integer pos = (Integer) group.getTag();
                switch (checkedId) {
                    case R.id.rbIterationYes:
                        //Check 'YES' and uncheck 'NO'
                        mSource.get(pos).setYesChecked(true);
                        mSource.get(pos).setNoChecked(false);
                        break;

                    case R.id.rbIterationNo:
                        //Vice versa
                        mSource.get(pos).setNoChecked(true);
                        mSource.get(pos).setYesChecked(false);
                        break;
                }
            }
        });

        row.setTag(holder);
    } else {
        holder = (ViewHolder) row.getTag();
    }
    holder.rbGroup.setTag(new Integer(position));
    holder.category.setText(mSource.get(position).getCategory());
    holder.question.setText(mSource.get(position).getDescription());
    //If no one of buttons isn't checked
    if (!mSource.get(position).isYesChecked() && !mSource.get(position).isNoChecked()) {
        holder.rbGroup.clearCheck();
    }else {
        //We are supposing 'YES' is checked
        int c = 0;
        //Or 'NO' is checked
        if (mSource.get(position).isNoChecked()){
            c = 1;
        }
        //Set checked button
        ((RadioButton)holder.rbGroup.getChildAt(c)).setChecked(true);
    }
    return row;
}
public class Question {

     private Integer id;
     private String category;
     private String description;
     private boolean yesChecked;
     private boolean noChecked;

/* Getters and setters */
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:id="@+id/tvQuestionCategory"/>
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:id="@+id/tvQuestion"/>

<RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/rgIteration">
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:id="@+id/rbIterationYes"
            android:text="@string/rbIterationYes"
            android:textSize="16dp"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:id="@+id/rbIterationNo"
            android:text="@string/rbIterationNo"
            android:textSize="16dp" />
</RadioGroup>

</LinearLayout>


我希望你能帮我找出错误,因为我已经完全厌倦了寻找解决方案。谢谢

您可以像这样覆盖getItemId方法并返回您的问题id,这样您就能够识别每个问题并使用id回答

public class RadioAdapter extends ArrayAdapter<Question> {

    List<Question> mSource;

    static class ViewHolder {
        TextView category = null;
        TextView question = null;
        RadioGroup rbGroup = null;

        ViewHolder(View row) {
            this.category = (TextView) row.findViewById(R.id.tvQuestionCategory);
            this.question = (TextView) row.findViewById(R.id.tvQuestion);
            this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration);
        }
    }

    private LayoutInflater mInflater;

    public RadioAdapter(Context context, List<Question> mSource) {
        super(context, R.layout.item_question, mSource);
        mInflater = LayoutInflater.from(context);
        this.mSource = mSource;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        View row = convertView;

        if (row == null) {
            row = mInflater.inflate(R.layout.item_question, null);

            holder = new ViewHolder(row);

            holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    //Get position of current group
                    //Integer pos = (Integer) group.getTag();
                    switch (checkedId) {
                        case R.id.rbIterationYes:
                            //Check 'YES' and uncheck 'NO'
                            mSource.get((int) getItemId(position)).setYesChecked(true);
                            mSource.get((int) getItemId(position)).setNoChecked(false);
                            break;

                        case R.id.rbIterationNo:
                            //Vice versa
                            mSource.get((int) getItemId(position)).setNoChecked(true);
                            mSource.get((int) getItemId(position)).setYesChecked(false);
                            break;
                    }
                }
            });

            row.setTag(holder);
        } else {
            holder = (ViewHolder) row.getTag();
        }
        holder.rbGroup.setTag(new Integer(position));
        holder.category.setText(mSource.get(position).getCategory());
        holder.question.setText(mSource.get(position).getDescription());
        //If no one of buttons isn't checked
        if (!mSource.get((int) getItemId(position)).isYesChecked() && !mSource.get((int) getItemId(position)).isNoChecked()) {
            holder.rbGroup.clearCheck();
        } else {
            //We are supposing 'YES' is checked
            int c = 0;
            //Or 'NO' is checked
            if (mSource.get((int) getItemId(position)).isNoChecked()) {
                c = 1;
            }
            //Set checked button
            ((RadioButton) holder.rbGroup.getChildAt(c)).setChecked(true);
        }
        return row;
    }

    @Override
    public long getItemId(int position) {
        return mSource.get(position).getId();
    }
}
公共类RadioAdapter扩展了ArrayAdapter{
列出mSource;
静态类视窗夹{
TextView类别=空;
TextView问题=null;
放射组rbGroup=null;
视图保持架(视图行){
this.category=(TextView)row.findViewById(R.id.tvQuestionCategory);
this.question=(TextView)row.findViewById(R.id.tvQuestion);
this.rbGroup=(放射组)row.findViewById(R.id.rgIteration);
}
}
私人停车场;
公共RadioAdapter(上下文,列表mSource){
super(上下文,R.layout.item_问题,mSource);
mInflater=LayoutInflater.from(上下文);
this.mSource=mSource;
}
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
ViewHolder=null;
视图行=转换视图;
if(行==null){
row=mInflater.充气(R.layout.item_问题,空);
支架=新的视图支架(行);
holder.rbGroup.setOnCheckedChangeListener(新的RadioGroup.OnCheckedChangeListener(){
检查更改后的公共无效(RadioGroup组,int checkedId){
//获取当前组的位置
//整数pos=(整数)group.getTag();
开关(检查EDID){
案例R.id.rbiteration是:
//勾选“是”,取消勾选“否”
mSource.get((int)getItemId(position)).setYesChecked(true);
mSource.get((int)getItemId(position)).setNoChecked(false);
打破
案例R.id.rbIterationNo:
//反之亦然
mSource.get((int)getItemId(position)).setNoChecked(true);
mSource.get((int)getItemId(position)).setYesChecked(false);
打破
}
}
});
row.setTag(支架);
}否则{
holder=(ViewHolder)row.getTag();
}
holder.rbGroup.setTag(新整数(位置));
holder.category.setText(mSource.get(position.getCategory());
holder.question.setText(mSource.get(position.getDescription());
//如果没有一个按钮未被选中
如果(!mSource.get((int)getItemId(position)).isYesChecked()&&!mSource.get((int)getItemId(position)).isNoChecked()){
holder.rbGroup.clearCheck();
}否则{
//我们假设勾选了“是”
int c=0;
//或勾选“否”
if(mSource.get((int)getItemId(position)).isNoChecked()){
c=1;
}
//设置选中按钮
((单选按钮)holder.rbGroup.getChildAt(c)).setChecked(true);
}
返回行;
}
@凌驾
公共长getItemId(int位置){
返回mSource.get(position.getId();
}
}

在将checked或unchecked设置为
radio组之前,应禁用侦听器,如下所示。希望这有帮助。
将适配器更改为此

public class RadioAdapter extends ArrayAdapter<Question> {

    List<Question> mSource;
    RadioGroup.OnCheckedChangeListener listener;
    static class ViewHolder {
        TextView category = null;
        TextView question = null;
        RadioGroup rbGroup = null;

        ViewHolder(View row) {
            this.category = (TextView) row.findViewById(R.id.tvQuestionCategory);
            this.question = (TextView) row.findViewById(R.id.tvQuestion);
            this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration);
        }
    }

    private LayoutInflater mInflater;

    public RadioAdapter(Context context, List<Question> mSource) {
        super(context, R.layout.item_question, mSource);
        mInflater = LayoutInflater.from(context);
        this.mSource = mSource;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        View row = convertView;

        if (row == null) {
            row = mInflater.inflate(R.layout.item_question, null);

            holder = new ViewHolder(row);
            listener = new RadioGroup.OnCheckedChangeListener() {

                public void onCheckedChanged(RadioGroup group, int checkedId) {

                    //Get position of current group
                    Integer pos = (Integer) group.getTag();
                    switch (checkedId) {
                        case R.id.rbIterationYes:
                            //Check 'YES' and uncheck 'NO'
                            mSource.get(pos).setYesChecked(true);
                            mSource.get(pos).setNoChecked(false);
                            break;

                        case R.id.rbIterationNo:
                            //Vice versa
                            mSource.get(pos).setNoChecked(true);
                            mSource.get(pos).setYesChecked(false);
                            break;
                    }
                }
            };
            holder.rbGroup.setOnCheckedChangeListener(listener);

            row.setTag(holder);
        } else {
            holder = (ViewHolder) row.getTag();
        }
        holder.rbGroup.setTag(new Integer(position));
        holder.category.setText(mSource.get(position).getCategory());
        holder.question.setText(mSource.get(position).getDescription());
        //If no one of buttons isn't checked
        holder.rbGroup.setOnCheckedChangeListener(null);
        if (!mSource.get(position).isYesChecked() && !mSource.get(position).isNoChecked()) {
            holder.rbGroup.clearCheck();
        }else {
            //We are supposing 'YES' is checked
            int c = 0;
            //Or 'NO' is checked
            if (mSource.get(position).isNoChecked()){
                c = 1;
            }
            //Set checked button

            ((RadioButton)holder.rbGroup.getChildAt(c)).setChecked(true);

        }
        holder.rbGroup.setOnCheckedChangeListener(listener);
        return row;
    }

}
公共类RadioAdapter扩展了ArrayAdapter{
列出mSource;
RadioGroup.OnCheckedChangeListener侦听器;
静态类视窗夹{
TextView类别=空;
TextView问题=null;
放射组rbGroup=null;
视图保持架(视图行){
this.category=(TextView)row.findViewById(R.id.tvQuestionCategory);
this.question=(TextView)row.findViewById(R.id.tvQuestion);
this.rbGroup=(放射组)row.findViewById(R.id.rgIteration);
}
}
私人停车场;
公共RadioAdapter(上下文,列表mSource){
super(上下文,R.layout.item_问题,mSource);
mInflater=LayoutInflater.from(上下文);
this.mSource=mSource;
}
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
ViewHolder=null;
视图行=转换视图;
if(行==null){
row=mInflater.充气(R.layout.item_问题,空);
支架=新的视图支架(行);
listener=新的RadioGroup.OnCheckedChangeListener(){
检查更改后的公共无效(RadioGroup组,int checkedId){
//获取当前组的位置
整数pos=(整数)group.getTag();
开关(检查EDID){
案例R.id.rbiteration是:
//勾选“是”,取消勾选“否”
mSource.get(pos.setYesChecked)(true);
mSource.get(pos.setNoChecked)(false);
打破
案例R.id.rbIterationNo:
//反之亦然
mSource.get(pos.setNoChecked)(true);
mSource.get(pos.setYesChecked)(false);
打破
}
}