Select only one radiobutton in a recyclerview
Asked Answered
S

9

12

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.

Sheepshank answered 5/2, 2016 at 7:36 Comment(2)
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.Domino
can you please elaborate a bit more on how the code should look?Sheepshank
S
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;
        }
    });
Sheepshank answered 29/4, 2016 at 5:29 Comment(1)
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.Gobelin
S
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.

Sheepshank answered 6/2, 2016 at 1:34 Comment(3)
When I select and remove, it automatically selects the ones below. Please help meLinneman
are you removing the check mark if it is clicked again?Sheepshank
Definitely yes @SheepshankLinneman
T
12

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();

                }
            });
        }
    }
}
Truthvalue answered 30/1, 2018 at 6:45 Comment(1)
this is for only one radio button in recyclerviewTheretofore
D
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;

        }
    });
Dextrorse answered 14/9, 2017 at 10:28 Comment(0)
N
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) }
    }
Negrophobe answered 29/12, 2020 at 9:30 Comment(0)
B
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
    }
Bursiform answered 3/12, 2021 at 10:36 Comment(0)
C
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
    }
Cepeda answered 5/2, 2023 at 17:32 Comment(0)
A
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.

Accompany answered 5/2, 2016 at 17:32 Comment(0)
T
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

Truce answered 11/12, 2017 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.