11

I have a recyclerview in which every item has 3 radiobuttons grouped in a radiogroup. Now a user can select only one radiobutton per item in recyclerview. But I want the user to select only one radiobutton throughout the recyclerview. How can this be achieved?

This is how it looks currently.

enter image description here

I would like to make it possible to check only 1 radiobutton throughout the recycler view. If 1st radio button in first item is checked and after that the user clicks on the 2nd radiobutton in 2nd item, then the 1st radiobutton in the 1st item should get unchecked.

suku
  • 10,507
  • 16
  • 75
  • 120
  • when ever user click on radio button save the id of radio button and call notifydatasetchanged() and in OnBindViewHolder check the radio button which u have saved while user clicking. – Anil Chandra Varma Dandu Feb 05 '16 at 07:40
  • can you please elaborate a bit more on how the code should look? – suku Feb 05 '16 at 12:35

9 Answers9

31

Here is another method to do the same. This is more elegant than my previous answer. But I have kept both as the previous answer provides more flexibility.

private RadioButton lastCheckedRB = null;
...
@Override
public void onBindViewHolder(final CoachListViewHolder holder, final int position) {
   holder.priceRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            RadioButton checked_rb = (RadioButton) group.findViewById(checkedId);
            if (lastCheckedRB != null) {
                lastCheckedRB.setChecked(false);
            }
            //store the clicked radiobutton
            lastCheckedRB = checked_rb;
        }
    });
suku
  • 10,507
  • 16
  • 75
  • 120
  • Not sure if something has changed since you posted this solution, but I implemented it and it works the first time each radio button is checked, but on subsequent clicks is seems that the call to lastCheckedRB.setChecked(false); is triggering the onCheckChanged to be called again which is causing the radio button to be unchecked. – Lehrian Jun 27 '21 at 17:45
19

Here is what worked for me:

 private RadioButton lastCheckedRB = null;
 ...
 @Override
 public void onBindViewHolder(final CoachListViewHolder holder, final int position) {
  View.OnClickListener rbClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            RadioButton checked_rb = (RadioButton) v;
            if(lastCheckedRB != null){
                lastCheckedRB.setChecked(false);
            }
            lastCheckedRB = checked_rb;
        }
    };

    //price_1m, price3m, price_6m are RadioButtons inside a radiogroup
    holder.price1m.setOnClickListener(rbClick);
    holder.price3m.setOnClickListener(rbClick);
    holder.price6m.setOnClickListener(rbClick);

Here, the radio button is stored temporarily in lastCheckedRB. When a new radio button is clicked, the old radiobutton is unchecked. Initially the lastCheckedRB is set to null.

suku
  • 10,507
  • 16
  • 75
  • 120
10

I used this approach

public class OffersRecyclerViewAdapter extends RecyclerView.Adapter<OffersRecyclerViewAdapter.ViewHolder> {

    private List<OffersModel> offersList;
    private Context context;

    private int lastSelectedPosition = -1;

    public OffersRecyclerViewAdapter(List<OffersModel> offersListIn, Context ctx) {
        offersList = offersListIn;
        context = ctx;
    }

    @Override
    public OffersRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.offer_item, parent, false);

        OffersRecyclerViewAdapter.ViewHolder viewHolder =
                new OffersRecyclerViewAdapter.ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(OffersRecyclerViewAdapter.ViewHolder holder, int position) {

        //since only one radio button is allowed to be selected,
        // this condition un-checks previous selections
        holder.selectionState.setChecked(lastSelectedPosition == position);
    }

    @Override
    public int getItemCount() {
        return offersList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public RadioButton selectionState;

        public ViewHolder(View view) {
            super(view);

         selectionState = (RadioButton) view.findViewById(R.id.offer_select);

            selectionState.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    lastSelectedPosition = getAdapterPosition();
                    notifyDataSetChanged();

                }
            });
        }
    }
}
Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
Developine
  • 12,483
  • 8
  • 38
  • 42
3

I faced issues with the accepted answer. Sometimes it makes currently checked radio button unchecked leaving non of the radio buttons selected. This was happening when selecting a radio button in different radio group after selecting a radio button from one group.

Here is the solution, instead of saving last checked RadioButton, save last checked RadioGroup and clear last check if last checked RadioGroup is not the current one and it has a selected RadioButton as shown below.

For more information read http://www.zoftino.com/android-recyclerview-radiogroup

   priceGroup = (RadioGroup) view.findViewById(R.id.price_grp);

    priceGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int i) {

            if (lastCheckedRadioGroup != null
                    && lastCheckedRadioGroup.getCheckedRadioButtonId()
                                     != radioGroup.getCheckedRadioButtonId()
                    && lastCheckedRadioGroup.getCheckedRadioButtonId() != -1) {
                lastCheckedRadioGroup.clearCheck();

                Toast.makeText(PackageRecyclerViewAdapter.this.context,
                        "Radio button clicked " + radioGroup.getCheckedRadioButtonId(),
                        Toast.LENGTH_SHORT).show();

            }
            lastCheckedRadioGroup = radioGroup;

        }
    });
Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
1

In Kotlin

private var checkedRadioButton: CompoundButton? = null
....
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    this.holder=holder

    val option = getItem(position)
    holder.txt_place_name.setText(option.toString())

    holder.itemView.radioButton.setOnCheckedChangeListener(checkedChangeListener)
    if (holder.itemView.radioButton.isChecked) checkedRadioButton = 
    holder.itemView.radioButton
    }
....
    private val checkedChangeListener = CompoundButton.OnCheckedChangeListener { 
    compoundButton, isChecked ->
    checkedRadioButton?.apply { setChecked(!isChecked) }
    checkedRadioButton = compoundButton.apply { setChecked(isChecked) }
    }
Sandeep Pareek
  • 1,636
  • 19
  • 21
1

KOTLIN 2021

Declare a RadioButton in a variable In your Adapter class

    private var lastCheckedRB: RadioButton? = null

Now In your Adapter class onBindViewHolder, Write OnclickListener to RadioButton

holder.YOURRADIOBUTTON.setOnClickListener {
        if (lastCheckedRB!=null){
            lastCheckedRB?.isChecked=false
        }
        lastCheckedRB = holder.YOURRADIOBUTTON
    }
G Anil Reddy
  • 19
  • 1
  • 6
1

To add onto G Anil Reddy answer:...

KOTLIN 2023

I have changed

lastCheckedRB = holder.YOURRADIOBUTTON

to:

lastCheckedRB = if (lastCheckedRB == holder.YOURRADIOBUTTON) null else holder.YOURRADIOBUTTON

This is in case the user clicks on the same radio button multiple times. It will uncheck and check each time to user clicks.


Declare a RadioButton in a variable In your Adapter class

private var lastCheckedRB: RadioButton? = null

Now In your Adapter class onBindViewHolder, Write OnclickListener to RadioButton

holder.YOURRADIOBUTTON.setOnClickListener {
        if (lastCheckedRB!=null){
            lastCheckedRB?.isChecked=false
        }
        lastCheckedRB = if (lastCheckedRB == holder.YOURRADIOBUTTON) null else holder.YOURRADIOBUTTON
    }
Tikhedewal
  • 23
  • 7
0

Try something similar:

public void onCheckedChanged(RadioGroup radioGroup, int checkedItemId) {
  mCheckedId = checkedItemId;
  mSelectedPosition = getAdapterPosition();
}

The code above is the listener you register to the RadioGroup inside onCreateViewHolder(). The prefixed items are your fields in the adapter.

In onBindViewHolder():

if (position == mSelectedPosition) {
  holder.radioGroup.check(mCheckedId);
} else {
  holder.radioGroup.clearCheck();
}

It should work this way.

razzledazzle
  • 6,900
  • 4
  • 26
  • 37
0
final String[] country_selcted = new String[1];
    holder.rb_team_one.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                        if(b==true)
                            country_selcted[0] =holder.rb_team_one.getText().toString();
                        else
                            country_selcted[0] =holder.rb_team_two.getText().toString();
                    }
                });

Now Print country_selcted[0] it gives you to row radio group selection result only

InsaneCat
  • 2,115
  • 5
  • 21
  • 40
Manoj Rawat
  • 260
  • 4
  • 6