Radiogroup in recyclerview

不羁的心 提交于 2019-12-03 04:56:08

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

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

}

}

this is what I did. In my onBindViewHolder

if(visualScore[position] == 1 ){
                holder.rg.check(R.id.rb_1);
            }else{
                if(audioScore[position] == 1){
                    holder.rg.check(R.id.rb_2);
                }else{
                    if(kinestScore[position] == 1){
                        holder.rg.check(R.id.rb_3);
                    }else{
                        holder.rg.clearCheck();
                    }
                }
            }
            holder.rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
                    switch (checkedId) {
                        case (R.id.rb_1):
                            visualScore[position] = 1;
                            audioScore[position] = 0;
                            kinestScore[position] = 0;
                            break;
                        case (R.id.rb_2):
                            visualScore[position] = 0;
                            audioScore[position] = 1;
                            kinestScore[position] = 0;
                            break;
                        case (R.id.rb_3):
                            visualScore[position] = 0;
                            audioScore[position] = 0;
                            kinestScore[position] = 1;
                            break;
                    }
        });

I declared all the score arrays as private global methods in the adapter class. Then, when submit button is clicked :

int v = 0, a = 0, k = 0;
                    for (int i = 0; i < Questions.length; i++){
                        v += visualScore[i];
                        a += audioScore[i];
                        k += kinestScore[i];
                    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!