问题
I made a RecyclerView that shows 32 question and 4 answers as RadioButton
s. 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 OnCheckedChangeListener
s, 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