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.