1

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);
        }
    }

The moment when the app boot up is OK (screenshot link).

When I scrolled down and scrolled up again, the RadioGroup of question 1 got duplicated (screenshot link).

When I tried scrolled down and up the third time, question #1 RadioGroup got triplicate, this happens for all the View that added by dynamic way, not just only the one of question #1 (screenshot link).

Minh Ho
  • 53
  • 4
  • Its better if you do not Create dynamic views inside Adapter(This degrades performance) . Except you can create multiple layouts for separete view types and just use them. – ADM Feb 24 '21 at 05:10
  • Is it possible to create dynamic view in every layout? because my radioButtons and checkBoxes number varies for every quiz. – Minh Ho Feb 24 '21 at 05:24
  • 1
    Well in this case you have to create it dynamically . What you need to do is call `linearLayout.removeAllView()` before adding views to it . You can Also have a `RecyclerView` inside `RecyclerView` and create as many views inside it . i think this is better way to do it . i.e Use a `recyclerView` to add radio/checkboxes . – ADM Feb 24 '21 at 05:27
  • Thank you! It ~linearLayout.removeAllView() does work properly! Now I need to dig more about adding more layout to improve performance. Thank you! – Minh Ho Feb 24 '21 at 05:35

0 Answers0