Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Radiogroup in recyclerview

I am having a recyclerview where each list item has a radiogroup with 4 radio buttons. How can I store the state of each radiogroup correctly. Here is my code. On scrolling up/down the states are incorrects. Thanks

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

    private List<Element> elements = new ArrayList<>();
    private Context context;

    private int[] state;

    public ElementListAdapter(Context context, List<Element> elements) {
        this.context = context;
        this.elements = elements;

        this.state = new int[elements.size()];
        Arrays.fill(this.state, -1);
    }

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

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final Element ele = elements.get(position);
        final String title = ele.getTitle();
        final String description = ele.getDescription();

        // Set text
        holder.tvTitle.setText(title);
        holder.tvDesciption.setText(description);

        if (ele.isHeader()) {                
            holder.radioGroup.setVisibility(View.GONE);
        } else {               
            holder.radioGroup.setVisibility(View.VISIBLE);
        }

        setRadio(holder, this.state[position]);



        holder.rb1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                state[position] = 0;
                setRadio(holder, state[position]);
            }
        });
        holder.rb2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                state[position] = 1;
                setRadio(holder, state[position]);
            }
        });
        holder.rb3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                state[position] = 2;
                setRadio(holder, state[position]);
            }
        });
        holder.rb4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                state[position] = 3;
                setRadio(holder, state[position]);
            }
        });


    }

    private void setRadio(final ViewHolder holder, int selection) {

        System.out.println("SELECT:" + selection);
        RadioButton b1 = holder.rb1;
        RadioButton b2 = holder.rb2;
        RadioButton b3 = holder.rb3;
        RadioButton b4 = holder.rb4;

        b1.setChecked(false);
        b2.setChecked(false);
        b3.setChecked(false);
        b4.setChecked(false);

        if (selection == 0) b1.setChecked(true);
        if (selection == 1) b2.setChecked(true);
        if (selection == 2) b3.setChecked(true);
        if (selection == 3) b4.setChecked(true);
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public View view;
        public TextView tvTitle;
        public TextView tvDesciption;

        public RadioGroup radioGroup;
        public RadioButton rb1, rb2, rb3, rb4;


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

            view = itemView;
            tvTitle = (TextView) itemView.findViewById(R.id.title);
            tvDesciption = (TextView) itemView.findViewById(R.id.description);

            radioGroup = (RadioGroup) itemView.findViewById(R.id.radioGroup);
            rb1 = (RadioButton) itemView.findViewById(R.id.rb1);
            rb2 = (RadioButton) itemView.findViewById(R.id.rb2);
            rb3 = (RadioButton) itemView.findViewById(R.id.rb3);
            rb4 = (RadioButton) itemView.findViewById(R.id.rb4);

        }
    }

}
like image 566
sujithvm Avatar asked Nov 02 '15 11:11

sujithvm


People also ask

How to use Radio group in RecyclerView?

The best way and the most efficient to do this is to simply add a variable which holds the option(radio button selected) to the class. And after onClick() just assign which radio button is selected to the variable and fetch that. First, add a variable in your Element class which stores the radio button option selected.


2 Answers

The best way saving your item state is placing the state variable inside the item model of the list, ex : "Element" in your case, than inside onBindViewHolder set the state based on your model, in your case:

change this :setRadio(holder, this.state[position]);

to this : setRadio(holder, elements.get(position).getState());

and

inside onClick methods

ex: for the first one change this: state[position] = 0; setRadio(holder, this.state[position]);

to this : elements.get(position).setState(0); setRadio(holder, elements.get(position).getState());

like image 58
KRist Avatar answered Sep 20 '22 19:09

KRist


The best way and the most efficient to do this is to simply add a variable which holds the option(radio button selected) to the class. And after onClick() just assign which radio button is selected to the variable and fetch that.

First, add a variable in your Element class which stores the radio button option selected.

Then,

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

private List<Element> elements = new ArrayList<>();
private Context context;

//instance of interface created
final private ListItemClickListener myOnClickListener;

private int[] state;

//create a interface which helps to communicates with your main activity
public interface ListItemClickListener
{
    void onListItemClick(int clickItemIndex,String optionSelected);
}
public ElementListAdapter(Context context, List<Element> elements) {
    this.context = context;
    this.elements = elements;

    this.state = new int[elements.size()];
    Arrays.fill(this.state, -1);
}

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

    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    final Element ele = elements.get(position);
    final String title = ele.getTitle();
    final String description = ele.getDescription();

    // Set text
    holder.tvTitle.setText(title);
    holder.tvDesciption.setText(description);

    if (ele.isHeader()) {                
        holder.radioGroup.setVisibility(View.GONE);
    } else {               
        holder.radioGroup.setVisibility(View.VISIBLE);
    }

  holder.setIsRecyclable(false);

  //here you check the option selected
    switch (Element.getUserOption()) {
           case "1":
                   holder.rb1.setChecked(true);
               break;
           case "2":
                   holder.rb2.setChecked(true);
               break;
           case "3":
                   holder.rb3.setChecked(true);
               break;
           case "4":
                   holder.rb4.setChecked(true);
               break;
           default:
               holder.radioGroup.clearCheck();
      }
}

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

//make sure to implement onClickListener here
public static class ViewHolder extends RecyclerView.ViewHolder implements View.onClickListener {

    public View view;
    public TextView tvTitle;
    public TextView tvDesciption;
    public int clickedCardPosition;

    public RadioGroup radioGroup;
    public RadioButton rb1, rb2, rb3, rb4;


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

        view = itemView;
        tvTitle = (TextView) itemView.findViewById(R.id.title);
        tvDesciption = (TextView) itemView.findViewById(R.id.description);

        radioGroup = (RadioGroup) itemView.findViewById(R.id.radioGroup);
        rb1 = (RadioButton) itemView.findViewById(R.id.rb1);
        rb2 = (RadioButton) itemView.findViewById(R.id.rb2);
        rb3 = (RadioButton) itemView.findViewById(R.id.rb3);
        rb4 = (RadioButton) itemView.findViewById(R.id.rb4);

        rb1.setOnClickListener(this);
        rb2.setOnClickListener(this);
        rb3.setOnClickListener(this);
        rb4.setOnClickListener(this);

    }


@Override
    public void onClick(View view) {

        int clickedCardPosition = getAdapterPosition();

        if(rb1.isPressed()) myOnClickListener.onListItemClick(clickedCardPosition, "1");
        if(rb2.isPressed()) myOnClickListener.onListItemClick(clickedCardPosition,"2");
        if(rb3.isPressed()) myOnClickListener.onListItemClick(clickedCardPosition,"3");
        if(rb4.isPressed()) myOnClickListener.onListItemClick(clickedCardPosition,"4");

    }

}
}

Then, in your activity where you are assigning the adapter, implement the Interface.

//implement here
public class YourMainActivity extends AppCompatActivity implements 
recyclerAdapter.ListItemClickListener{
.
.
.
.
.
@Override
public void onListItemClick(int clickItemIndex, String optionSelected) {

       //Here assign the value to the Element Obj
        yourList.get(clickItemIndex).setUserOption(optionSelected);
        yourAdapter.notifyDataSetChanged();

}

}
like image 36
sac Avatar answered Sep 24 '22 19:09

sac