RadioGroup не поддерживает правильное состояние в ListView

Я знаю о проблеме повторного использования ListView и пытаюсь сохранить свое состояние в модели, но, похоже, это не работает. Прочитал много тем с такой же проблемой, но их решения мне не подходят, или я что-то не так делаю. Когда я прокручиваю список вверх и вниз с группой радио в исходном состоянии, ничего не происходит, это правильно. Но как только я устанавливаю флажок любой радиокнопки в любой строке, а затем прокручиваю его вверх и вниз, радиокнопки становятся проверенными случайным образом.

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;
}

}

Вопрос.java:

public class Question {

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

/* Getters and setters */
}

item_question.xml:

<?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>

Я надеюсь, что вы можете помочь мне найти ошибки, потому что я совершенно устал искать решение. Спасибо


person viRUS    schedule 07.03.2016    source источник
comment
Отладьте свой код и проверьте правильную позицию в Integer pos = (Integer) group.getTag(); иholder.rbGroup.setTag (новое целое число (позиция)); на этих строках кода.   -  person Wasim K. Memon    schedule 07.03.2016
comment
Отладка показывает правильные позиции, но когда я прокручиваю вверх и вниз, иногда работает public void onCheckedChanged (группа RadioGroup, int checkedId)   -  person viRUS    schedule 07.03.2016
comment
Я уже решил эту проблему с флажком, проверьте его, надеюсь, он будет работать и с радиогруппой. androprogrammer.com/2013/10/   -  person Wasim K. Memon    schedule 07.03.2016
comment
Это все еще не работает   -  person viRUS    schedule 08.03.2016
comment
вы уже храните идентификатор вопроса, тогда зачем вам нужна позиция. просто используйте идентификатор в качестве идентификатора, а затем проверьте, проверено ли да или нет или нет.   -  person Wasim K. Memon    schedule 08.03.2016


Ответы (2)


Прежде чем вы настроите Checked или Unchecked для вашего RadioGroup, вы должны отключить прослушиватель, как это. Надеюсь это поможет. Поменяй адаптер на этот

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;
    }

}
person Debanjan    schedule 08.03.2016

Вы можете сделать так, чтобы переопределить метод getItemId и вернуть свой идентификатор вопроса, чтобы вы могли идентифицировать каждый вопрос и ответ с помощью идентификатора.

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();
    }
}
person Wasim K. Memon    schedule 08.03.2016