Radiogroup in recyclerview

杀马特。学长 韩版系。学妹 提交于 2019-12-03 13:49:31

问题


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

        }
    }

}

回答1:


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




回答2:


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

}

}



回答3:


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];
                    }


来源:https://stackoverflow.com/questions/33476951/radiogroup-in-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!