首页 > 解决方案 > Check radio buttons status in Recycle View Adapter and applying changes to it from MainActivity

问题描述

In my MainActivity method checkAnswer and showSolution are have to be modified because I added RecycleView adapter to the project and moved all view items to the QuestionAdapter. I do not understand how should I check status of rbGroup radio buttons using isChecked in QuestionAdapter and pass its id to MainActivity. I tried to check this: Radiogroup in recyclerview but it is still unclear to me what steps should i take next. Can someone give me basic instruction, what steps should be taken in modifying my project from now. Still can't find answer or tutorial for handling radio button list in Recycle view. How to check radio button status using interface from MainActivity?

Made some updates as was suggested. Do not understand how should i modify showSolution method.

public class MainActivity extends AppCompatActivity {

public QuestionAdapter adapter;
public ArrayList<Question> questionList;
private int questionCountTotal;
private long backPressedTime;
private int score;
private int questionCounter;
private Button btnConfirmNext;
private boolean answered;
private Question currentQuestion;
private TextView tvQuestion, tvScore, tvQuestionCount, tvCountdown;
public QuizDbHelper dbHelper;
RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btnConfirmNext = findViewById(R.id.confirm_button);
    tvCountdown = findViewById(R.id.count_down);
    tvScore = findViewById(R.id.text_view_score);

    recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setNestedScrollingEnabled(false);
    recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));
    questionList = new ArrayList<>();
    adapter = new QuestionAdapter(this, questionList);

    RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 1);
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(adapter);

    dbHelper = new QuizDbHelper(this);
    questionList = dbHelper.getAllQuestions();
    questionCountTotal = questionList.size();
    Collections.shuffle(questionList);

        prepareQuestion();

    btnConfirmNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            checkAnswer();
        }
    });

}


private void prepareQuestion() {
    adapter = new QuestionAdapter(getApplicationContext(), questionList);
    recyclerView.setAdapter(adapter);
    if (questionCounter < questionCountTotal) {
        currentQuestion = questionList.get(questionCounter);

        answered = false;
        btnConfirmNext.setText("Confirm");

    } else {
        finishQuiz();
    }
}


//How should I handle it in onbindViewHolder

private void checkAnswer() {
    answered = true;
    countDownTimer.cancel();
    RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
    int answerNb = rbGroup.indexOfChild(rbSelected) + 1;

    if (answerNb == currentQuestion.getAnswerNB()) {
        score++;
        tvScore.setText("Score: " + score);
    }
    showSolution();
}

//How should I change state of the items in recycle view

private void showSolution() {
    rb1.setTextColor(Color.RED);
    rb2.setTextColor(Color.RED);
    rb3.setTextColor(Color.RED);
    rb4.setTextColor(Color.RED);

    switch (currentQuestion.getAnswerNB()) {
        case 1:
            rb1.setTextColor(Color.GREEN);
            break;
        case 2:
            rb2.setTextColor(Color.GREEN);
            break;
        case 3:
            rb3.setTextColor(Color.GREEN);
            break;
        case 4:
            rb4.setTextColor(Color.GREEN);
            break;
    }

    btnConfirmNext.setText("Finish");

}

QuestionAdapter

public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.MyViewHolder> {

public ArrayList<Question> questionList;

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView tvQuestion, tvScore, tvQuestionCount, tvCountdown;
    public RadioGroup rbGroup;
    public RadioButton rb1, rb2, rb3, rb4;



    public MyViewHolder(View view) {
        super(view);
        tvQuestion = view.findViewById(R.id.question);
        rbGroup = view.findViewById(R.id.radiog_group);
        rb1 = view.findViewById(R.id.radio_button1);
        rb2 = view.findViewById(R.id.radio_button2);
        rb3 = view.findViewById(R.id.radio_button3);
        rb4 = view.findViewById(R.id.radio_button4);
    }
}


public QuestionAdapter(Context mContext, ArrayList<Question> questionList) {
    this.questionList = questionList;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.question_card, parent, false);


    return new MyViewHolder(itemView);
}

@NonNull
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    final Question question = questionList.get(position);
    holder.tvQuestion.setText(question.getQuestion());
    holder.rb1.setText(question.getOption1());
    holder.rb2.setText(question.getOption2());
    holder.rb3.setText(question.getOption3());
    holder.rb4.setText(question.getOption4());

    holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {

// How can I handle Check status here and pass it to main activity?

        }
    });
}

@Override
public int getItemCount() {
    return questionList.size();
}
}

UPDATE. After adding interface to my QuestionAdapter and apllying changes to constructor and other parts, my checkAnswer in MainActivity looks like this

    private void checkAnswer() {
    answered = true;
    countDownTimer.cancel();
    adapter = new QuestionAdapter(getApplicationContext(), questionList, new QuestionAdapter.OnItemListener() {
        @Override
        public void onItemSelect(int position) {
           if (position+1==currentQuestion.getAnswerNB()){
               score++;
               tvScore.setText("Score: " + score);
           }
        }
        });
    showSolution();
}

Now what should I do with my showSolution method? It seems like after checkAnswer i should send information back to QuestionAdapter and do setTextColor there. Probably i went wrong way...

MainActivity

标签: androidandroid-recyclerviewradio-buttonradio-grouponcheckedchanged

解决方案


你可以通过使用界面来做到这一点。

创建一个这样的接口:

public interface OnItemListener {
    public void onItemSelect(int position);
}

然后在您的适配器中更改构造函数,如下所示:

  QuestionAdapter(Context mContext, ArrayList<Question> questionList, OnItemListener 
  onItemListener) {
        this.onItemListener = onItemListener;
        this.questionList = questionList;
    }

并将这一行添加到您的 onCheckedChangeListener

            onItemListener.onItemSelect(position);

像这样:

holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {

        // How can I handle Check status here and pass it to main activity?
        onItemListener.onItemSelect(position);
        }
    });

然后在你的活动中添加这个你定义适配器的地方(它是定义适配器的另一种方式,你也可以使用你自己的方式只记得添加这样的接口(新的 OnItemListener ...)):

 dbHelper = new QuizDbHelper(getApplicationContext(), questionList, new 
 OnItemListener({

            @Override
            public void onItemSelect(int position) {
             // handle your check state of adapter item here
            }

        });

推荐阅读