In my application am displaying 20 multiple choice questions with the help of RecyclerView
.
If I change the value of first RadioGroup
and scrolls down, again scrolls up removing the selected value in RecycelarView
and also i want to use that selected RadioButton
value further, I was also checked link1 but i did't understood what he is doing.
Here is my sample code snippet let me know if you need any clarification.
package com.testing.survey; import java.util.List; import android.annotation.SuppressLint; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; @SuppressWarnings("rawtypes") public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> { private List<Student> stList; public DataAdapter(List<Student> students) { this.stList = students; } // Create new views @Override public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate( R.layout.list_row, null); // create ViewHolder ViewHolder viewHolder = new ViewHolder(itemLayoutView); return viewHolder; } @SuppressLint("UseValueOf") @Override 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).getAnswer4()); //viewHolder.rgAnswers.clearCheck(); viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId()); viewHolder.rgAnswers.setTag(new Integer(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()).intValue(); //Student contact=(Student)group.getTag(); //contact.setSelectedRadioButtonId(radioButtonID); stList.get(clickedPos).setSelectedRadioButtonId(radioButtonID); Log.v("hello"+clickedPos,stList.get(clickedPos).getSelectedRadioButtonId()+""); } }); } // Return the size arraylist @Override public int getItemCount() { return stList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView tvQuestionNumber; public TextView tvQuestion; public RadioGroup rgAnswers; public RadioButton rbAns1,rbAns2,rbAns3,rbAns4,rbAns5; public Student singlestudent; public ViewHolder(View itemLayoutView) { super(itemLayoutView); tvQuestionNumber = (TextView) itemLayoutView.findViewById(R.id.tvQuestionNumber); tvQuestion = (TextView) itemLayoutView.findViewById(R.id.tvQuestion); rgAnswers=(RadioGroup)itemLayoutView.findViewById(R.id.rgAnswers); rbAns1=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer1); rbAns2=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer2); rbAns3=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer3); rbAns4=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer4); rbAns5=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer5); } } // method to access in activity after updating selection public List<Student> getStudentist() { return stList; } }
By default it have 5.
This viewType variable is internal to the Adapter class. It's used in the onCreateViewHolder() and onBindViewHolder to inflate and populate the mapped layouts. Before we jump into the implementation of the Adapter class, let's look at the types of layouts that are defined for each view type.
It's more efficient by default, the layout is separated and we have more possibilities over the data set inside the adapter. The ViewHolder pattern allows us to make our list scrolling act smoothly.
This problem occurs because of a bug in either RecyclerView
or somewhere in the Android SDK. Anyway, I took the advice from another SO question - onCheckedChanged called automatically.
For RadioGroup
, it will be a little different. There are two ways to go about. I recommend 1st one since it is plug-n-play.
set OnCheckedChangeListener
on RadioGroup
:
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if(checkedId == -1) { Log.v("onCheck", "Android bug since RadioButton doesn't get unchecked normally!"); } else { Log.v("onCheck", "Valid click. By user"); mMyListObjectArr[position].setChecked(checkedId); } } });
or set onCheckedChangeListener
on all RadioButton
s inside the RadioGroup
:
CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(buttonView.isPressed()) { Log.v("onCheck", position + ", valid click by user"); mMyListObjectArr[position].setChecked(buttonView.getId()); } else { Log.v("onCheck", "Android bug"); } } }; mRadioButton1.setOnCheckedChangeListener(onCheckedChangeListener); mRadioButton2.setOnCheckedChangeListener(onCheckedChangeListener);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With