Radio button checked by itself when scrolling

我与影子孤独终老i 提交于 2020-05-15 09:26:38

问题


I made a RecyclerView that shows 32 question and 4 answers as RadioButtons. When I click a single radio button, it works, and I show a toast when it is checked.

But when I scroll the RecyclerView`, it shows toasts like I checked a radio button.

How do I fix it?

My adapter:

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

    private int[] integer;
    String option[];
    private OnRadioChangeListener onRadioChangeListener;

    public sikapadapter(String[] option, OnRadioChangeListener onRadioChangeListener) {
        this.option = option;
        this.onRadioChangeListener = onRadioChangeListener;
        integer = new int[option.length];
    }

    interface OnRadioChangeListener{
        void onRadioChange(int position,int checkedId);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.recycleview_sikap_layout,parent,false);
        sikapadapter.ViewHolder aadvh = new sikapadapter.ViewHolder(view);
        return aadvh;
    }

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

        if(integer[position] == 1){
            holder.radio.check(R.id.radiobutton1);
        }else if(integer[position] == 2){
            holder.radio.check(R.id.radiobutton2);
        }else if(integer[position] == 3){
            holder.radio.check(R.id.radiobutton3);
        }else if(integer[position] == 4){
            holder.radio.check(R.id.radiobutton4);
        }else {
            holder.radio.clearCheck();
        }

        holder.text.setText(option[position]);

        holder.radio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if(onRadioChangeListener!=null){
                    if(checkedId == R.id.radiobutton1){
                        checkedId = 1;
                        integer[position] = 1;
                        onRadioChangeListener.onRadioChange(position,checkedId);
                    }

                    if(checkedId == R.id.radiobutton2){
                        checkedId = 2;
                        integer[position] = 2;
                        onRadioChangeListener.onRadioChange(position,checkedId);
                    }

                    if(checkedId == R.id.radiobutton3){
                        checkedId = 3;
                        integer[position] = 3;
                        onRadioChangeListener.onRadioChange(position,checkedId);
                    }

                    if(checkedId == R.id.radiobutton4){
                        checkedId = 4;
                        integer[position] = 4;
                        onRadioChangeListener.onRadioChange(position,checkedId);

                    }

                }
            }
        });


    }

    @Override
    public int getItemCount() {
        return option.length;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView text;
        RadioGroup radio;
        RadioButton radio1,radio2,radio3,radio4;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            text = itemView.findViewById(R.id.recytexttampil);
            radio = itemView.findViewById(R.id.radiogroup);
            radio1 = itemView.findViewById(R.id.radiobutton1);
            radio2 = itemView.findViewById(R.id.radiobutton2);
            radio3 = itemView.findViewById(R.id.radiobutton3);
            radio4 = itemView.findViewById(R.id.radiobutton4);


        }
    }
}

Like this - I never checked adapter position 19, but when I scroll it checks itself:


回答1:


Calling radio.check triggers any OnCheckedChangeListeners, so when onBindViewHolder is called for a recycled ViewHolder, the listener that was attached from the previous bind is triggered.

To solve it, remove the listener, set the correct checked item, then set the new listener.

For example:

// Clear the listener so we don't trigger it
holder.radio.setOnCheckedChangeListener(null);

// Set the correct item to checked
if(integer[position] == 1){
    holder.radio.check(R.id.radiobutton1);
} else if (...) {
    // ...handle other cases here, removed to keep the example short...
}

holder.text.setText(option[position]);

// Put the listener back to watch for new changes
holder.radio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
    //...



回答2:


Try to clear all checked buttons and radio group listener before setting the selected one in the onBindViewHolder()

    holder.radio.clearCheck();

    // clear the listener of previous rows
    holder.radio.setOnCheckedChangeListener(null); 


    if(integer[position] == 1){
        holder.radio.check(R.id.radiobutton1);
    }else if(integer[position] == 2){
        holder.radio.check(R.id.radiobutton2);
    }else if(integer[position] == 3){
        holder.radio.check(R.id.radiobutton3);
    }else if(integer[position] == 4){
        holder.radio.check(R.id.radiobutton4);
    }else {
        holder.radio.clearCheck();
    }
    ... 


来源:https://stackoverflow.com/questions/61691017/radio-button-checked-by-itself-when-scrolling

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