Error while selecting an option in a dynamically generated, multiple RadioGroup Layout. Some of the radio buttons are automatically getting checked

StackOverflow https://stackoverflow.com/questions/8793796

Question

I have a list of 10 multiple choice questions and each question have a "RadioGroup". But when ever I'm selecting a option for a question, some of the options of other questions are getting automagically selected.

Suppose I selected a option for question - 1. then question numbers - 5, 9 are automatically selected with the same option.

When I select a option for question - 2, question numbers - 6, 10 are automatically selected with the same option.

This shouldn't be happen. When ever I select a option, only that option in that RadioGroup should get checked. Please help me to fix this.

I'm developing an Mobile Based Test. When ever the user enters his username and password, the server will authenticates that. For authorized users, it will returns a question paper as a JSONObject. And Each exam will have an exam_id and a list of 10 Multiple Choice Questions while each question have one unique "id", "question" and four options "A","B","C" and "D" as follows. The "questions" object is a JSONArray.

{
"exam_id": 0, 
"questions": [
    {
        "A": "A", 
        "C": "c", 
        "B": "b",      
        "D": "d", 
        "question": "A", 
        "id": 1, 
    }, 
    {
        "A": "a", 
        "C": "c", 
        "B": "B", 
        "D": "d", 
        "question": "B", 
        "id": 2, 
    },

    ....
    ....

]
}

By using ListAdapter, I'm trying to assign these values to a list. Here is the Activity for that...

public class MBTExam extends ListActivity {

JSONObject result;
String exam_id;
JSONArray question_list_json;
ArrayList<String> question_list;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test);

    Bundle extras = getIntent().getExtras();
    try {
        result = new JSONObject(extras.getString("result"));
        exam_id = result.getString("exam_id");
        question_list_json = result.getJSONArray("questions");

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

        for (int i = 1; i <= question_list_json.length() ; i++) {

            HashMap<String, String> map = new HashMap<String, String>();
            JSONObject e = question_list_json.getJSONObject(i-1);

            map.put("id", new Integer(i).toString());
            map.put("question", e.getString("question"));
            map.put("A", e.getString("A"));
            map.put("B", e.getString("B"));
            map.put("C", e.getString("C"));
            map.put("D", e.getString("D"));

            mylist.add(map);
        }

        ListAdapter adapter = new SimpleAdapter(this, 
                mylist,
                R.layout.mbt_test,
                new String[] { "id", "question", "A", "B", "C", "D" },
                new int[] { R.id.question_no, R.id.question, R.id.A, R.id.B, R.id.C, R.id.D });

        setListAdapter(adapter);

    } catch (JSONException e) {
        Log.e("log_tag", "Error parsing data " + e.toString());
    }

}
}

Here is the row layout for each question

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top" >

<TextView
    android:id="@+id/question_no"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignWithParentIfMissing="true" />

<TextView
    android:id="@+id/white_space"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/question_no"
    android:text="@string/white_space" />

<TextView
    android:id="@+id/question"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/white_space" />

<RadioGroup
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/question" >

    <RadioButton
        android:id="@+id/A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RadioButton
        android:id="@+id/B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RadioButton
        android:id="@+id/C"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RadioButton
        android:id="@+id/D"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RadioGroup>

</RelativeLayout>

and here is the layout for the "MBTExam"

<?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:gravity="top" >
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/android:list">
</ListView>
<Button
    android:id="@+id/submit"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="Submit"/>
</LinearLayout>

Also, Along with the questions, I have to get a submit button at the end of the paper. Please suggest me the necessary changes in my layout code.

Here is my complete source code

Thanks in advance.

Was it helpful?

Solution

SimpleAdapter, like all good adapter implementations recycles/reuses views in it's getView implementation. You are seeing unexpected radio button selections when a view that had a selection in its previous position is reused in another position in the ListView.

You will need to either use a custom ViewBinder with your existing SimpleAdapter, or create your own Adapter class to control how views are reused.

This answer to a similar question seems like a good place to start:

To make your submit button appear in your layout, give your ListView a layout weight value of "1" within a vertical LinearLayout:

<?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:gravity="top"
android:orientation="vertical" >
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:id="@+id/android:list" />
<Button
    android:id="@+id/submit"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="Submit"/>
</LinearLayout>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top