4

I am developing an app which has a list view with custom layout as follows :
It has 4 RadioButtons in RadioGroup and a TextView. Actually, it ll be shown as question(TextView) and answers(RadioButtons) list. Above view is inflated in my custom adapter which extends ArrayAdapter<Question>.

The problem is that, how should I maintain the state of RadioButtons in my custom Adapter? When RadioButton is pressed/checked and list is scrolled down, adapter automatically recycles view and the RadioButton state is lost.

  • So, can anyone guide to any link / information regarding this?
  • Or how should I implement question answers list?

Article I followed: http://www.vogella.de/articles/AndroidListView/article.html .

The above link is using a CheckBox, in similar manner I want to use the RadioGroup(RadioButtons) instead of CheckBoxes.

user
  • 86,916
  • 18
  • 197
  • 190
Rohit
  • 2,538
  • 6
  • 28
  • 41

1 Answers1

16

It's easy to adapt that tutorial so you can use a RadioGroup instead of a CheckBox. Bellow is an example(I used a RadioGroup with 4 RadioButton). First of all you'll have to modify the Model class so it can hold the new data:

public class Model {

    String question; // hold the question
    int current = NONE; // hold the answer picked by the user, initial is NONE(see below)
    public static final int NONE = 1000; // No answer selected
    public static final int ANSWER_ONE_SELECTED = 0; // first answer selected
    public static final int ANSWER_TWO_SELECTED = 1; // second answer selected
    public static final int ANSWER_THREE_SELECTED = 2; // third answer selected
    public static final int ANSWER_FOUR_SELECTED = 3; // forth answer selected

    public Model(String question) {
        this.question = question;  
    }

}

Then modify the getView() method to set the views according to the model:

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            ViewHolder holder = null;

            if (v == null) {
                v = inflater.inflate(R.layout.the_row, parent, false);
                holder = new ViewHolder(v);
                v.setTag(holder);
                holder.group
                        .setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

                            public void onCheckedChanged(RadioGroup group,
                                    int checkedId) {
                                Integer pos = (Integer) group.getTag(); // To identify the Model object i get from the RadioGroup with getTag()
                                                                        //  an integer representing the actual position 
                                Model element = list.get(pos);          
                                switch (checkedId) { //set the Model to hold the answer the user picked
                                case R.id.answer0:
                                    element.current = Model.ANSWER_ONE_SELECTED;
                                    break;
                                case R.id.answer1:
                                    element.current = Model.ANSWER_TWO_SELECTED;
                                    break;
                                case R.id.answer2:
                                    element.current = Model.ANSWER_THREE_SELECTED;
                                    break;
                                case R.id.answer3:
                                    element.current = Model.ANSWER_FOUR_SELECTED;
                                    break;
                                default:
                                    element.current = Model.NONE; // Something was wrong set to the default
                                }

                            }
                        });
            } else {
                holder = (ViewHolder) v.getTag();
            }
            holder.group.setTag(new Integer(position)); // I passed the current position as a tag

            holder.t.setText(list.get(position).question); // Set the question body

            if (list.get(position).current != Model.NONE) {
                RadioButton r = (RadioButton) holder.group.getChildAt(list
                        .get(position).current);
                r.setChecked(true);
            } else {
                holder.group.clearCheck(); // This is required because although the Model could have the current 
                                           // position to NONE you could be dealing with a previous row where
                                           // the user already picked an answer. 

            }
            return v;
        }

and then ViewHolder class:

class ViewHolder {
    TextView t = null;
    RadioGroup group;

    ViewHolder(View v) {
        t = (TextView) v.findViewById(R.id.textView1);
        group = (RadioGroup) v.findViewById(R.id.group_me);
    }

}

The xml layout with a RadioGroup:

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

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RadioGroup
        android:id="@+id/group_me"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/answer0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="Ans0" />

        <RadioButton
            android:id="@+id/answer1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="Ans1" />

        <RadioButton
            android:id="@+id/answer2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="Ans2" />

        <RadioButton
            android:id="@+id/answer3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="Ans3" />
    </RadioGroup>

</LinearLayout>
user
  • 86,916
  • 18
  • 197
  • 190
  • can u pls tell me more about " Model element = list.get(pos); " this line – Rohit Mar 03 '12 at 07:09
  • 1
    @rohit Normally the `OnCheckedChangeListener` doesn't know the position of the element in the list on which the user checked. So we set a `TAG` object(an integer) representing the position you get from the `getView()` method, and then on the line `Model element = list.get(pos);` we get the model element corresponding to the actual position on which the user checked something. It's like the 8. part of that tutorial but instead of passing the model object directly we set as tag the position and then retrieve the model object based on that position. – user Mar 03 '12 at 07:18
  • i copied my question object list into Model object list and that worked.. thx :) – Rohit Mar 03 '12 at 07:57