Search code examples
androidkotlinandroid-recyclerviewandroid-constraintlayout

RecyclerView is Not Displaying Adapter's Data


My RecyclerView is displaying empty CardView. I don't see where I went wrong. Android Studio doesn't fail at compile tile and the app doesn't fail during run time either. Any help will be appreciated.

This is my data class

data class Notes(
    var title: String,
    var description: String
)

This is my adapter

class MyNotesAdapter(private val notesList: MutableList<Notes>) : RecyclerView.Adapter<MyNotesAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var textViewTitle: TextView = view.findViewById(R.id.textViewTitle)
        var textViewDescr: TextView = view.findViewById(R.id.textViewDescr)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        var view = LayoutInflater.from(parent.context).inflate(R.layout.my_notes_adapter_layout,
            parent, false) 
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textViewTitle.text = notesList[position].title
        holder.textViewDescr.text = notesList[position].description
    }

    override fun getItemCount(): Int = notesList.size
}

This is my adapter layout

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="16dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dp">
        <TextView
            android:id="@+id/textViewTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TITLE HERE"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            android:textColor="@color/black"
            app:layout_constraintTop_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />
        <TextView
            android:id="@+id/textViewDescr"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="DESCR HERE"
            android:textColor="@color/black"
            app:layout_constraintTop_toBottomOf="@id/textViewTitle"
            app:layout_constraintStart_toStartOf="@id/textViewTitle"
            app:layout_constraintEnd_toEndOf="@id/textViewTitle" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.card.MaterialCardView>

That is how I setup my RecyclerView in my main activity

private fun setupRecyclerView() {
    val myNotesAdapter: MyNotesAdapter = MyNotesAdapter(notesList)
    val linearLayoutManager: LinearLayoutManager = LinearLayoutManager(this)
    linearLayoutManager.orientation = RecyclerView.VERTICAL

    recyclerViewNotes = findViewById(R.id.recyclerViewNotes)
    recyclerViewNotes.layoutManager = linearLayoutManager
    recyclerViewNotes.adapter = myNotesAdapter
}

My RecyclerView function gets called here

private fun setupDialogBox() {
        var view = LayoutInflater.from(this).inflate(R.layout.add_notes_dialog_layout, null)
        var dialog = AlertDialog.Builder(this)
            .setView(view)
            .setCancelable(false)
            .create()
        dialog.show()

        buttonSubmit = view.findViewById(R.id.buttonSubmit)
        editTextTitle = view.findViewById(R.id.editTextTitle)
        editTextDescr = view.findViewById(R.id.editTextDescr)

        buttonSubmit.setOnClickListener {
            notes = Notes(editTextTitle.text.toString(), editTextDescr.text.toString())
            notesList.add(notes)
            setupRecyclerView()
            dialog.hide()
        }
    }

My dialog gets called within main activity onCreate()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_my_notes)
    ......

    fabButton.setOnClickListener {
        setupDialogBox()
    }
}

Solution

  • <TextView
        android:id="@+id/textViewTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TITLE HERE"
        ....
        app:layout_constraintTop_toBottomOf="parent" />
    

    The problem is in the ConstraintLayout as the app:layout_constraintTop_toBottomOf="parent" of the top TextView is set to the bottom of the ConstraintLayout.

    This includes that the height of the ConstraintsLayout is calculated from match_parent i.e. it equals to the parent (so, it takes the full height of the item layout), and therefore the TextViews won't be shown on the List item or on the screen.

    Also as the CardView height is wrap_content, then the ConstraintLayout will tend to take the minimum possible height to that ViewGroup.

    To fix this you need to replace this constraint of the textViewTitle:

    `app:layout_constraintTop_toBottomOf="parent"`
    

    With:

    `app:layout_constraintTop_toTopOf="parent"`