Проблема с выбором элемента RecyclerView

Я разрабатываю приложение для живой викторины, которое извлекает данные с сервера, и вопрос отображается в RecyclerView, который содержит вопрос и четыре варианта. Теперь, когда я выбираю один вариант для данного вопроса, он выбирается правильно, но в то же время автоматически выбирается соответствующий вариант для другого вопроса.

Снимок экрана с проблемой выбора элемента выглядит следующим образом. Проблема с выбором элемента RecyclerView Я разработал класс модели данных и адаптер RecylerView (с помощью @Reaz Murshed), но застрял в коде Мой класс модели данных: //DmLiveQuiz

public class DmLiveQuiz {
String testId;
int questionId;
String question;
String optA;
String optB;
String optC;
String optD;
String answer;
String explain;
... 
}

Мой класс адаптера //LiveTestAdapter

public class LiveTestAdapter extends RecyclerView.Adapter<LiveTestAdapter.CustomViewHolder> {
private List<DmLiveQuiz> questionList;
private int[] answerList; // Get a list of your answers here.
private DmLiveQuiz questionsList;
private Context context;
public List<Integer> myResponse = new ArrayList<Integer>();
public int qno;
public LiveTestAdapter(List<DmLiveQuiz> questionList, Context context) {
this.questionList = questionList;
this.context = context;
}
@NonNull
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.live_quiz_display_format, parent, false);
return new CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull final CustomViewHolder holder, int position) {
questionsList = questionList.get(holder.getAdapterPosition());
holder.tvQNo.setText(questionsList.getQuestionId() + "");
holder.tvquestion.getLayoutParams().width = LinearLayout.LayoutParams.WRAP_CONTENT;
holder.tvquestion.setText(questionsList.getQuestion());
holder.optA.setText(questionsList.getOptA());
holder.optB.setText(questionsList.getOptB());
holder.optC.setText(questionsList.getOptC());
holder.optD.setText(questionsList.getOptD());
// Now you need to modify the backgrounds of your option buttons like the following.
if (answerList[position] == 1) holder.optA.setBackgroundResource(R.drawable.button_border);
else holder.optA.setBackgroundResource(R.drawable.button_question_style);
if (answerList[position] == 2) holder.optB.setBackgroundResource(R.drawable.button_border);
else holder.optB.setBackgroundResource(R.drawable.button_question_style);
if (answerList[position] == 3) holder.optC.setBackgroundResource(R.drawable.button_border);
else holder.optC.setBackgroundResource(R.drawable.button_question_style);
if (answerList[position] == 4) holder.optD.setBackgroundResource(R.drawable.button_border);
else holder.optD.setBackgroundResource(R.drawable.button_question_style);
holder.optA.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.optA.setBackgroundResource(R.drawable.button_border);
answerList[position] = 1; // Selected first option which is A
});
holder.optB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.optB.setBackgroundResource(R.drawable.button_border);
answerList[position] = 2; // Selected second option which is B
Toast.makeText(context, "Position :" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
                        }
                    });
holder.optC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.optC.setBackgroundResource(R.drawable.button_border);
answerList[position] = 3; // Selected third option which is C
 Toast.makeText(context, "Position :" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
holder.optD.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.optD.setBackgroundResource(R.drawable.button_border);
answerList[position] = 4; // Selected fourth option which is D
Toast.makeText(context, "Position :" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
                        }
                    });
holder.tvClear.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
holder.optA.setBackgroundResource(R.drawable.button_question_style);
holder.optB.setBackgroundResource(R.drawable.button_question_style);
holder.optC.setBackgroundResource(R.drawable.button_question_style);
holder.optD.setBackgroundResource(R.drawable.button_question_style);
answerList[position] = 0; // Clear the value in the answerList
}
});
}

// Use this function to set the question list in the adapter
public void setQuestionList(List<DmLiveQuiz> questionList) {
this.questionList = questionList;
this.answerList = new int[questionList.size()]; // This initializes the answer list having the same size as the question list
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return questionList.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
TextView tvquestion, tvClear, tvQNo;
Button optA, optB, optC, optD;
public CustomViewHolder(View itemView) {
super(itemView);
tvQNo = (TextView) itemView.findViewById(R.id.tvLiveQuizQuestionNo);
tvquestion = (TextView) itemView.findViewById(R.id.tvLiveQuizQuestion);
optA = (Button) itemView.findViewById(R.id.buttonOptionA);
...///
}
}
}

И действие, в котором реализован Recyclerview,

recyclerView = (RecyclerView) findViewById(R.id.recyclerViewLiveTest);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
quizList = new ArrayList<>();
adapter = new LiveTestAdapter(quizList, getApplicationContext());
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
// recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setAdapter(adapter);
getData();
        ......

Метод получения данных JSON - это getdata(), как указано ниже, который правильно извлекает данные с сервера...

private void getData() {
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(quiz_url, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
DmLiveQuiz liveQuiz = new DmLiveQuiz();
...
...
quizList.add(liveQuiz);
} catch (JSONException e) {
e.printStackTrace();
progressDialog.dismiss();
}
}
adapter.notifyDataSetChanged();
..........
}



    Now When I run App, it shows index=0 i.e. ArrayOutOfIndexException is generated.. I am not able to call public void setQuestionList(List<DmLiveQuiz> questionList) method of LiveQuizAdapter class  from my activity.. Please Help
0
0
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Изначально вы устанавливаете пустой список в адаптере. После получения значения из JsonArrayRequest необходимо обновить адаптер, используя новый список.

Обновление наBindViewHolder:

@Override
public void onBindViewHolder(@NonNull final CustomViewHolder holder, int position) {
DmLiveQuiz  dmLiveQuiz= questionList.get(position);
if (dmLiveQuiz!=null){
// do whatever you want. put all code here.}

}

Обновите адаптер:

    @Override
    public void onResponse(JSONArray response) {
    for (int i = 0; i < response.length(); i++) {
// put all code here
    quizList.add(liveQuiz);}
    adapter.setQuestionList(quizList);
    adapter.notifyDataSetChanged();
    }

Большое спасибо, брат. Вы сделали мой день. Будьте здоровы. С вашей любезной помощью я могу решить проблемы. Еще раз спасибо.

Ramesh Thakur 22.04.2019 19:54

Вы гений, сэр.

Ramesh Thakur 22.04.2019 20:03

вам нужно добавить логическое значение в класс модели DmLiveQuiz: -

boolean isSelected ;

а затем установите флажок в своем адаптере, пока вы показываете, выбран ли ответ или нет: -

if (DmLiveQuiz.isSelectd){
// this is the selected answer
}else {
// in case don't selected
}

и измените логическое значение в элементе адаптера. Нажмите

Уважаемый сэр, я еще не реализовал ваше решение. Спасибо за ответ. Я сообщу вам о прогрессе, которого я добился после реализации ваших предложений по коду. Еще раз спасибо.

Ramesh Thakur 22.04.2019 19:56

Другие вопросы по теме