简体   繁体   中英

How to use Radiogroup with 4 different Radio Button In ArrayAdapter

I have a custom List Adapter that has a question in a Text View and four options as an answer in Radio Buttons. All the Radio Buttons are bound together in a Radio Group. The problem is that I cannot keep track of the buttons that are checked.On scrolling the buttons get checked on random. How can I store the radio buttons that are checked for a particular


public class MCQAdapter extends ArrayAdapter {

public MCQAdapter(Activity context, ArrayList<MCQ> mcq) {
    super(context, 0, mcq);
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View listItemView = convertView;

    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(R.layout.activity_mcqlist, parent, false);
    }


    final MCQ currentContent = (MCQ) getItem(position);
    TextView content = (TextView) listItemView.findViewById(R.id.Question_Block);
    content.setText(currentContent.getQuestion());

    RadioGroup rg = (RadioGroup) listItemView.findViewById(R.id.Radio_Group);

    final RadioButton rb1 = (RadioButton) listItemView.findViewById(R.id.Option1_Block);
    rb1.setText(currentContent.getOptionA());

    final RadioButton rb2 = (RadioButton) listItemView.findViewById(R.id.Option2_Block);
    rb2.setText(currentContent.getOptionB());

    final RadioButton rb3 = (RadioButton) listItemView.findViewById(R.id.Option3_Block);
    rb3.setText(currentContent.getOptionC());

    final RadioButton rb4 = (RadioButton) listItemView.findViewById(R.id.Option4_Block);
    rb4.setText(currentContent.getOptionD());

    return listItemView;

}

}

public class MCQ {

String question,optionA,optionB,optionC,optionD,answer,userAnswer;

public MCQ(String quest,String a,String b,String c, String d,String ans){

    question = quest;
    optionA = a;
    optionB = b;
    optionC = c;
    optionD = d;
    answer = ans;

}

public String getQuestion(){
    return question;
}

public String getOptionA() {
    return optionA;
}

public String getOptionB() {
    return optionB;
}

public String getOptionC() {
    return optionC;
}

public String getOptionD() {
    return optionD;
}

public String getAnswer() {
    return answer;
}

public String getUserAnswer() {
    return userAnswer;
}

public void setUserAnswer(String userAnswer) {
    this.userAnswer = userAnswer;
}

}

public class PropertiesOfConstructionMaterail extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_properties_of_construction_materail);

    final ArrayList<MCQ> mcq = new ArrayList<MCQ>();

    //Creating Different Instance Of MCQ to genarte various questions for Properties of Consrtuction Material
    mcq.add(new MCQ("The property of material by which it can be beaten or rolled into thin plates, is called ?",
            "Malleability","Ductility","Plasticity","Elasticity","Malleability"));
    mcq.add(new MCQ("The property by which a body returns to its original shape after removal of the force, is called ?",
            "Plasticity","Elasticity","Ductility","Malleability","Elasticity"));
    mcq.add(new MCQ("The property of a material by which it can be drawn into smaller section due to tension, is called ?"
            ,"Plasticity","Ductility","Elasticity","Malleability","Ductility")); 

MCQAdapter adapter = new MCQAdapter(this,mcq);

    ListView listView = (ListView) findViewById(R.id.list);
    listView.setAdapter(adapter);
}

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_mcqlist"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.silen.civilengineeringmcq.MCQList"
android:orientation="vertical">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Question_Block"
    android:textSize="18dp"
    android:textStyle="bold"/>

<RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Radio_Group">

    <RadioButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Option1_Block"
        android:checked="false"/>

    <RadioButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Option2_Block"
        android:checked="false"/>

    <RadioButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Option3_Block"
        android:checked="false"/>

    <RadioButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Option4_Block"
        android:checked="false"/>

</RadioGroup>

You should create a wrapper around your PoJo class (MCQ), name it ViewModel, which store the current state of view inside adapter. In your case that state is a state of radio buttons.

It will looks like:

class ViewModel extends MCQ {
    MCQ mcq;

    int radioButtonSelectedId;

    public ViewModel(MCQ mcq) {
        this.mcq = mcq;
        this.radioButtonSelectedId = R.id.Option1_Block;
    }

    public void setRadioButtonSelectedId(int id) {
        this.id = id;
    }

    public int getRadioButtonSelectedId() {
        return id;
    }

    //delegates to mcq getter/setter methods
}

Your getView method:

public View getView(int position, View convertView, ViewGroup parent) {
//your logic above
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                viewModel.setRadioButtonSelectedId(checkedId);
            }
        });

    //same for other radio buttons
    rb1.setChecked(viewModel.getRadioButtonSelectedId() == R.id.Option1_Block);
//your logic below
}

So as i mention above, your array list inside adapter would contain ViewModel s wrappers, not MCQ classes directly

final ArrayList<ViewModel> mcqList = new ArrayList<>();
MCQ mcq = new MCQ("The property of material by which it can be beaten or rolled into thin plates, is called ?",
        "Malleability","Ductility","Plasticity","Elasticity","Malleability")
mcqList.add(new ViewModel(mcq));

I think you should get an option

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM