In my application am displaying 20 multiple choice questions with the help of RecyclerView
.
If I change the value of first RadioGroup
and s
Modify your onBindViewHolder()
to this
public void onBindViewHolder(ViewHolder viewHolder, int position) {
final int pos = position;
viewHolder.tvQuestionNumber.setText(stList.get(position).getQuestionNumber() + "");
viewHolder.tvQuestion.setText(stList.get(position).getQuestion());
viewHolder.rbAns1.setText(stList.get(position).getAnswer1());
viewHolder.rbAns2.setText(stList.get(position).getAnswer2());
viewHolder.rbAns3.setText(stList.get(position).getAnswer3());
viewHolder.rbAns4.setText(stList.get(position).getAnswer4());
viewHolder.rbAns5.setText(stList.get(position).getAnswer5());
//viewHolder.rgAnswers.clearCheck();
viewHolder.rgAnswers.setTag(position);
Log.v("select" + position, stList.get(position).getSelectedRadioButtonId() + "");
viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// TODO Auto-generated method stub
int radioButtonID = group.getCheckedRadioButtonId();
View radioButton = group.findViewById(radioButtonID);
int clickedPos = (Integer) group.getTag();
stList.get(clickedPos).setSelectedRadioButtonId(radioButtonID);
// if you want to get selected button's info such as tag, text... etc.
RadioButton radioButton = (RadioButton) viewHolder.itemView.findViewById(radioButtonID);
if(radioButton != null) {
String customTag = radioButton.getTag().toString();
stList.get(clickedPos).setCustomTag(customTag);
}
Log.v("hello" + clickedPos, stList.get(clickedPos).getSelectedRadioButtonId() + "");
}
});
viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId());
}
It should work. If any issues please let me know.
Inside your student class add a boolean variable isSelected. Now on checkedChangeListener of each radiogroup, change the value of isSelected to mark whether some value has been selected or no selection has been made. Now inside onBindViewHolder() just do
if(stList.get(position).isSelected){
viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId());
}else{
viewHolder.rgAnswers.clearCheck();
}
At the end you can iterate over the whole list and check for which objects, isSelected is true
The problem is that the recycler view is recycling (like the name says) your views.
The system creates a certain amount of ViewHolders to fill your screen after reaching that amount it reuses the already existent ViewHolders.
If you set the button checked in your first listentry and it reuses the ViewHolder for your 7th listentry the button is still checked(because it got set in the ViewHolder).
To fix this problem you need to set the default appearance for your listentries in onBindViewHOlder every time.
Update:
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
final Student student = stList.get(position);
viewHolder.tvQuestionNumber.setText(student.getQuestionNumber());
viewHolder.tvQuestion.setText(student.getQuestion());
viewHolder.rbAns1.setText(student.getAnswer1());
viewHolder.rbAns2.setText(student.getAnswer2());
viewHolder.rbAns3.setText(student.getAnswer3());
viewHolder.rbAns4.setText(student.getAnswer4());
viewHolder.rbAns5.setText(student.getAnswer4());
viewHolder.rgAnswers.clearCheck();
viewHolder.rgAnswers.check(student.getSelectedRadioButtonId());
viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
student.setSelectedRadioButtonId(checkedId);
Log.v("hello"+position,checkedId+"");
}
});
}
I slightly updated your new approach, maybe this helps ?
In your model class add
private int checkedId = -1;
public int getCheckedId() {
return checkedId;
}
public void setCheckedId(int checkedId) {
this.checkedId = checkedId;
}
and change onBindViewHolder in adapter like this:
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.tvQuestion.setText(stList.get(position).getQuestion());
viewHolder.rbAns1.setText(stList.get(position).getAnswer1());
viewHolder.rbAns2.setText(stList.get(position).getAnswer2());
viewHolder.rbAns3.setText(stList.get(position).getAnswer3());
viewHolder.rbAns4.setText(stList.get(position).getAnswer4());
viewHolder.rbAns5.setText(stList.get(position).getAnswer5());
viewHolder.radGrp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup rgp, int checkedId) {
// TODO Auto-generated method stub
stList.get(position).setCheckedId(rgp.getCheckedRadioButtonId());
}
});
viewHolder.radGrp.check(stList.get(position).getCheckedId());
}
As i have seen your code...
just add single line
viewHolder.rgAnswers.setOnCheckedChangeListener(null);
in onBindViewHolder()
method above of this line
viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId());
...
if it solved your problem ..let me know ... i will explain you a scenario why its happening .. Because i faced similer problem and solved using this solution.
You can do it in this way.....
inside your bean class add one field say
String final_answer;
public String getFinalAnswer(){
return final_answer;
}
public void setFinalAnswer(String final_answer){
this.final_answer = final_answer;
}
in adapter.....
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
final Student student = stList.get(position);
viewHolder.tvQuestionNumber.setText(student.getQuestionNumber());
viewHolder.tvQuestion.setText(student.getQuestion());
viewHolder.rbAns1.setText(student.getAnswer1());
viewHolder.rbAns2.setText(student.getAnswer2());
viewHolder.rbAns3.setText(student.getAnswer3());
viewHolder.rbAns4.setText(student.getAnswer4());
viewHolder.rbAns5.setText(student.getAnswer4());
viewHolder.rgAnswers.clearCheck();
if(student.getSelectedRadioButtonId()!=null)
viewHolder.rgAnswers.check(student.getSelectedRadioButtonId());
else
viewHolder.rgAnswers.clearCheck();
viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId != -1){
student.setSelectedRadioButtonId(checkedId);
RadioButton rb = (RadioButton)viewHolder.rgAnswers.
findViewById(checkedId);
student.setFinalAnswer(rb.getText);
stList.get(position) = student;
}
}
});
}
To get selected answers finally...write this code in main activity
public void getSelectedAnswers(){
for(int i=0;i<slist.length;i++){
//get selected answer
Log.i("answer",slist.get(i).getFinalAnswer());
}
}