Saving Selected Radiobutton's Text In Model Class From Recyclerview Item
Solution 1:
The problem is that although the code looks correct on the surface, what's actually happening is that when you call holder.radioGroup.check()
, it triggers your onCheckedChanged()
event handler just the same as if the user had initiated it.
Since the views are recycled, the view at position 0 is being reused for position 8 in the list. So the call to check()
in onBindViewHolder()
will call onCheckedChanged()
, with the checked radio button from position 0 still checked (i.e. checkedId
and radioGroup. getCheckedRadioButtonId()
will return the ID of the radiobutton checked when the view was used at position 0).
The real crux is this
models.get(clickedPos).setChecked(radioButtonID);
Consider the first paragraphs of the answer, and you'll realize that this will (incorrectly) update the model item at position 8 with the radioButtonID
that was checked when this view was used at position 0.
One way to solve this is to distinguish between a user-initiated change and a binding-initiated change. You can for example do this by adding a field to the ViewHolder
to indicate if the view is currently binding.
classViewHolderextendsRecyclerView.ViewHolder{
TextView selectedAnswer;
RadioGroup radioGroup;
boolean isBinding;
ViewHolder(View itemView) {
super(itemView);
radioGroup = itemView.findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
publicvoidonCheckedChanged(RadioGroup group, int checkedId) {
int position = getAdapterPosition();
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
/* Only update the model when onCheckedChange() was initiated by the user clicking
a radio button, not when the adapter is binding the view. In that scenario, we
are only interested in passing information FROM the model TO the view. */if( !isBinding ) {
models.get(position).setChecked(checkedId);
models.get(position).setSelectedAns(radioButton != null ? radioButton.getText().toString() : "");
}
selectedAnswer.setText( models.get(position).getSelectedAns() );
}
});
...
}
}
@OverridepublicvoidonBindViewHolder(@NonNullfinal ViewHolder holder, finalint position) {
holder.isBinding = true;
...
/* When calling check() here, we invoke onCheckedChanged(), which will
update the textview that displays the selected answer - so no need to call
holder.selectedAnswer.setText( models.get(position).getSelectedAns() )
from here */
holder.radioGroup.check(models.get(position).getChecked());
holder.isBinding = false;
}
Post a Comment for "Saving Selected Radiobutton's Text In Model Class From Recyclerview Item"