Skip to content Skip to sidebar Skip to footer

Saving Selected Radiobutton's Text In Model Class From Recyclerview Item

From RecyclerView item, I am trying to save the selected RadioButton's text in model class. When I select a RadioButton from 1st item, it's text is saved appropriately. Problem is,

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"