我有一个带有自定义对象的arraylist,该对象存储回收视图的单选按钮状态。单选按钮的状态保存在recyclereview中,每次回收视图时,它都会携带状态。因此,我决定将单击按钮的状态存储在对象"RadioButtonStates"的数组列表中,该列表存储选中的id、单击的适配器位置以及是否单击了状态。我用伪值"false,0,0"填充了arraylist,在onclick方法中,我用set方法更改radiobuttonstate的值。但是set方法不起作用。我觉得问题是我指的是arraylist的一个实例,而不是arraylist。但是,当我将该方法声明为静态时,并没有什么区别。
public class WordQuestionAdapter extends RecyclerView.Adapter<WordQuestionAdapter.ViewHolder> {
Context mContext;
Random random = new Random();
ArrayList<WordMaps> wordList = new ArrayList<>();
//arraylist which stores buttonstates
private static ArrayList<RadioButtonStates> buttonStates = new ArrayList<>();
//universalViewHolder object allows to get an instance of the holder from onBindViewholder in order to use available methods.
ViewHolder universalViewHolder;
private RadioGroup radioGroup;
public WordQuestionAdapter(Context context, ArrayList<WordMaps> wordMapsArrayList) {
this.mContext = context;
this.wordList = wordMapsArrayList;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public CardView cardView;
public RadioButton meaning_1, meaning_2, meaning_3, meaning_4;
public RadioGroup radioGroup;
public ViewHolder(CardView view) {
super(view);
cardView = view;
meaning_1 = (RadioButton) cardView.findViewById(R.id.meaning_1);
meaning_2 = (RadioButton) cardView.findViewById(R.id.meaning_2);
meaning_3 = (RadioButton) cardView.findViewById(R.id.meaning_3);
meaning_4 = (RadioButton) cardView.findViewById(R.id.meaning_4);
radioGroup = (RadioGroup) cardView.findViewById(R.id.radio_group);
}
}
@Override
public WordQuestionAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView cV = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
radioGroup = (RadioGroup) cV.findViewById(R.id.radio_group);
//for loop which stores the dummy values in order to deal with NPE's
for(int i = 0; i<5999;i++){
buttonStates.add(i, (new RadioButtonStates(false, 0, 0)));
}
ViewHolder viewHolder = new ViewHolder(cV);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
Log.i("* Cases", "View binded");
universalViewHolder = holder;
final CardView cardView = holder.cardView;
int true_random_position = random.nextInt(wordList.size());
TextView wordText = (TextView) cardView.findViewById(R.id.word);
switch (random.nextInt(3)) {
case 0:
Log.i("* Cases", "Case 0 called");
wordText.setText(wordList.get(true_random_position).getWord());
holder.meaning_1.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_2.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_1);
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_2);
//Checks if radioButton is clicked. If boolean of getter and setter returns false,
//then value is not clicked.
if (!buttonStates.get(holder.getAdapterPosition()).getSetChecked()) {
Log.i("* RadioGroup", "radioGroup cleared");
holder.radioGroup.clearCheck();
} else {
Log.i("* RadioGroup", "radioGroup checked "+buttonStates.get(holder.getAdapterPosition()).getCheckedId());
holder.radioGroup.check(buttonStates.get(holder.getAdapterPosition()).getCheckedId());
}
break;
case 1:
Log.i("* Cases", "Case 1 called");
wordText.setText(wordList.get(true_random_position).getWord());
Log.i("position", "" + position);
Log.i("wordText", "" + wordList.get(true_random_position).getWord());
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_2);
//Checks if radioButton is clicked. If boolean of getter and setter returns false,
//then value is not clicked.
if (!buttonStates.get(holder.getAdapterPosition()).getSetChecked()) {
Log.i("RadioGroup", "radioGroup cleared");
holder.radioGroup.clearCheck();
} else {
Log.i("RadioGroup", "radioGroup checked"+buttonStates.get(holder.getAdapterPosition()).getCheckedId());
holder.radioGroup.check(buttonStates.get(holder.getAdapterPosition()).getCheckedId());
}
break;
case 2:
Log.i("* Cases", "Case 2 called");
wordText.setText(wordList.get(true_random_position).getWord());
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_3.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_3);
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_2);
//Checks if radioButton is clicked. If boolean of getter and setter returns false,
//then value is not clicked.
if (!buttonStates.get(holder.getAdapterPosition()).getSetChecked()) {
holder.radioGroup.clearCheck();
Log.i("* RadioGroup", "radioGroup checked" + buttonStates.get(holder.getAdapterPosition()).getCheckedId());
} else {
holder.radioGroup.check(buttonStates.get(holder.getAdapterPosition()).getCheckedId());
Log.i("* RadioGroup", "radioGroup checked" + buttonStates.get(holder.getAdapterPosition()).getCheckedId());
}
break;
case 3:
Log.i("* Cases", "Case 3 called");
wordText.setText(wordList.get(true_random_position).getWord());
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(true_random_position).getMeaning());
onRadioButtonClicked(R.id.meaning_4);
holder.meaning_1.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_2.setText(wordList.get(true_random_position).getMeaning());
holder.meaning_3.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
holder.meaning_4.setText(wordList.get(random.nextInt(wordList.size())).getMeaning());
onRadioButtonClicked(R.id.meaning_2);
//Checks if radioButton is clicked. If boolean of getter and setter returns false,
//then value is not clicked.
if (!buttonStates.get(holder.getAdapterPosition()).getSetChecked()) {
holder.radioGroup.clearCheck();
} else {
//else value is clicked
holder.radioGroup.check(buttonStates.get(holder.getAdapterPosition()).getCheckedId());
}
}
Log.i("* Adapter Position", ""+universalViewHolder.getAdapterPosition());
}
//Radiobutton which checks if the object being clicked is the right one
public void onRadioButtonClicked(final int checkButtonSelect){
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
universalViewHolder.getAdapterPosition();
if(checkedId!=-1) {
Log.i("* checkedButtonId", "" + checkedId);
if (checkedId == checkButtonSelect) {
buttonStates.set(universalViewHolder.getAdapterPosition(), new RadioButtonStates(true, checkedId, universalViewHolder.getAdapterPosition()));
//log statements which check if values were changed. Always returns false"
Log.i("* ButtonState id", "" + buttonStates.get(universalViewHolder.getAdapterPosition()).getCheckedId());
Log.i("* ButtonState position", "" +buttonStates.get(universalViewHolder.getAdapterPosition()).getAdapterPosition());
Toast.makeText(mContext, "CORRECT", Toast.LENGTH_SHORT).show();
} else {
buttonStates.set(universalViewHolder.getAdapterPosition(), new RadioButtonStates(true, checkedId, universalViewHolder.getAdapterPosition()));
//log statements which check if values were changed. Always returns false"
Log.i("* ButtonState boolean", "" + buttonStates.get(universalViewHolder.getAdapterPosition()).getSetChecked());
Log.i("* ButtonState id", "" + buttonStates.get(universalViewHolder.getAdapterPosition()).getCheckedId());
Log.i("* ButtonState position", "" +buttonStates.get(universalViewHolder.getAdapterPosition()).getAdapterPosition());
Toast.makeText(mContext, "INCORRECT", Toast.LENGTH_SHORT).show();
}
}
}
});
}
@Override
public int getItemCount() {
return wordList.size();
}
}
UPDATE:set()
方法确实有效,但它只在屏幕上可见的最终位置有效。也就是说,在这种情况下,单击时只会将选项设置在位置2,忽略0和1。我将尝试将holder的值传递给方法本身。例如onRadioButtonClicked(final int checkButtonSelect, final ViewHolder holder
。希望这种语法能解决问题。
问题是universalViewHolder
只保存了最后一个持有者引用,没有实时访问持有者。因此,当我想更改buttonstates
数组列表中的数据时,我遇到了一个巨大的问题,因为它不会更改单击位置的值,而是更改onBindViewHolder
中持有者的最终引用处的值。当通过接受两个参数调用时,通过将onRadioButtonClicked
更改为接受holder
的直接引用来获得直接引用,我可以直接访问适配器位置。