Home > Software design >  Recycleview items are not shown on app Kotlin/Android
Recycleview items are not shown on app Kotlin/Android

Time:10-05

I'm making a quiz app and want to show the questions on the app by using a recycleview but for some reason, the questions are not shown.

My data class for the question:

    data class Question(
        val questionText: String,
        val isCorrect: Boolean
    )

The QuestionAdapter:

    class QuestionAdapter(private val questions: List<Question>) : RecyclerView.Adapter<QuestionAdapter.ViewHolder>() {
    
        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    
            val binding = ItemQuestionBinding.bind(itemView)
    
            fun databind(question: Question) {
                binding.tvQuestion.text = question.questionText
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder(
                LayoutInflater.from(parent.context).inflate(R.layout.item_question, parent, false)
            )
        }
    
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.databind(questions[position])
        }
    
        override fun getItemCount(): Int {
            return questions.size
        }
    }

The MainActivity (questions are still hard coded):

    class MainActivity : AppCompatActivity() {
        private val questions = arrayListOf<Question>()
        private val questionAdapter = QuestionAdapter(questions)
        private lateinit var binding: ActivityMainBinding
    
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
            initViews()
    
        }
    
        private fun initViews() {
            binding.rvQuestions.layoutManager = LinearLayoutManager(this@MainActivity, RecyclerView.VERTICAL, false)
            binding.rvQuestions.adapter = questionAdapter
            binding.rvQuestions.addItemDecoration(DividerItemDecoration(this@MainActivity, DividerItemDecoration.VERTICAL))
    
            questions.addAll(generateQuestions())
            questionAdapter.notifyDataSetChanged()
    
        }
    
        /**
         * Generate questions static for now
         */
        private fun generateQuestions(): ArrayList<Question> {
            return arrayListOf(
                Question("A 'val' and 'var' are the same", false),
                Question("MAD grants 12 ECTS", false),
                Question("Java and Kotlin syntax is the same", false),
                Question("Kotlin 'when' operator replaces the 'switch' operator in Java", true),
                Question("A Unit in Kotlin corresponds to a void in Java", true),
            )
        }
    }

My activity main xml:

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <TextView
            android:id="@ id/txtTitle"
            style="@style/TextAppearance.MaterialComponents.Headline5"
            android:layout_width="302dp"
            android:layout_height="89dp"
            android:layout_marginTop="16dp"
            android:gravity="start"
            android:text="@string/quiz_instructions"
            app:layout_constraintHorizontal_bias="0.146"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@ id/txtSecTitle"
            style="@style/TextAppearance.MaterialComponents.Headline6"
            android:layout_width="302dp"
            android:layout_height="89dp"
            android:layout_marginTop="44dp"
            android:gravity="start"
            android:text="@string/answer_instructions"
            app:layout_constraintHorizontal_bias="0.146"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@ id/rvQuestions"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    
    
    </androidx.constraintlayout.widget.ConstraintLayout>

And my item_question xml:

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="72dp"
        xmlns:tools="http://schemas.android.com/tools">
    
    
    
        <TextView
            android:id="@ id/tvQuestion"
            style="@style/MaterialAlertDialog.MaterialComponents.Title.Text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="Use tools:text to see preview text only in editor" />
    </androidx.constraintlayout.widget.ConstraintLayout>

I have used this similar setup in another project to show a list view of items, there it worked fine. But here the questions are not shown when the app starts.

CodePudding user response:

You should use this initialize

    private val questions = arrayListOf<Question>()
    private val questionAdapter = QuestionAdapter(questions)

by this way

    private lateinit var questionAdapter : QuestionAdapter

then you can pass the (questions) here

    questions.addAll(generateQuestions())
    binding.rvQuestions.layoutManager = LinearLayoutManager(this@MainActivity, RecyclerView.VERTICAL, false)
    binding.rvQuestions.adapter = questionAdapter
    binding.rvQuestions.addItemDecoration(DividerItemDecoration(this@MainActivity, DividerItemDecoration.VERTICAL))
    questionAdapter.notifyDataSetChanged()

this way the initialization is correct and now the items will show

CodePudding user response:

You complicated the adapter initialisation. remove this line

    private val questionAdapter = QuestionAdapter(questions)

and change the function as shown below.

private fun initViews() {
            binding.rvQuestions.layoutManager = LinearLayoutManager(this@MainActivity, RecyclerView.VERTICAL, false)
            questions.addAll(generateQuestions())
            binding.rvQuestions.addItemDecoration(DividerItemDecoration(this@MainActivity, DividerItemDecoration.VERTICAL))  
            binding.rvQuestions.adapter = QuestionAdapter(questions)             
        }

Now it should work. Use notify data changed only when required. its expensive one.

need reference have a look at this tutorial.

  • Related