My project is making a Quiz app using Recycler View. Single view layout is a LinearLayout with one TextVIew showing quiz question, code as below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txtQuiz"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
Quizzes have 3 types:
- Type0: multiple choices and single correct answer -> dynamically adds RadioGroup and its relative RadioButtons.
- Type1: multiple choices and multiple correct answers -> dynamically adds CheckBoxes.
- Type2: entry answer -> dynamically adds EditView.
I manage to add dynamic Views successfully but every time I scroll the screen, the off-screen views when they show back, those that added dynamically by code are getting duplicated, and the order also messed up sometimes (like RadioGroup in question #1 got duplicate and added to question #3, etc ...).
I got the ViewHolder constructor like this:
public ViewHolder(View itemView) {
super(itemView);
tvQuiz = (TextView) itemView.findViewById(R.id.txtQuiz);
linearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);
}
And onBindViewHolder method:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Quiz quiz = quizzes.get(position);
TextView textView = holder.tvQuiz;
textView.setText(quiz.getQuiz());
LinearLayout linearLayout = holder.linearLayout;
if (quiz instanceof QuizType0) {
RadioGroup radioGroup = new RadioGroup(linearLayout.getContext());
// Type0: multiple choices and single correct answer
//-> dynamically adds RadioGroup and its relative RadioButtons.
for (String s : ((QuizType0) quiz).getOptionsList()) {
RadioButton radioButton = new RadioButton(linearLayout.getContext());
radioButton.setText(s);
linearLayout.setHasTransientState(true);
radioGroup.addView(radioButton);
linearLayout.setHasTransientState(false);
}
linearLayout.setHasTransientState(true);
linearLayout.addView(radioGroup);
linearLayout.setHasTransientState(false);
}
// Type1: multiple choices and multiple correct answers
// -> dynamically adds CheckBoxes.
if (quiz instanceof QuizType1) {
for (String s : ((QuizType1) quiz).getOptionsList()) {
CheckBox checkBox = new CheckBox(linearLayout.getContext());
checkBox.setText(s);
linearLayout.setHasTransientState(true);
linearLayout.addView(checkBox);
linearLayout.setHasTransientState(false);
}
}
// Type2: entry answer
// -> dynamically adds EditView.
if (quiz instanceof QuizType2) {
EditText editText = new EditText(linearLayout.getContext());
linearLayout.setHasTransientState(true);
linearLayout.addView(editText);
linearLayout.setHasTransientState(false);
}
}