-1

I'm trying to implement a onClickListener for my Kotlin RecyclerView. It's simply not firing. The code isn't marked red or something like that. The Log and Toast you see in the NotesActivity.kt are not being executed. My recyclerview is working in itself, but simply the onClickListener wouldn't fire.

NotesAdapter.kt

class NotesAdapter(private val dataSet: MutableList<Note>) :
    RecyclerView.Adapter<NotesAdapter.ViewHolder>() {

var clickListener: ClickListener? = null

inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {


    val textViewTitle: TextView
    val textViewBody: TextView

    init {
        // Define click listener for the ViewHolder's View.
        textViewTitle = view.findViewById(R.id.textViewTitle)
        textViewBody = view.findViewById(R.id.textViewBody)

        if (clickListener != null) {
            itemView.setOnClickListener(this)
        }
    }

    override fun onClick(view: View?) {
        if (view != null) {
            clickListener?.onItemClick(view, adapterPosition)
        }
    }
}

fun setOnItemClickListener(clickListener: ClickListener) {
    this.clickListener = clickListener
}

interface ClickListener {
    fun onItemClick(v: View, position: Int)
}

// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
    // Create a new view, which defines the UI of the list item
    val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.adapter_note_layout, viewGroup, false)

    return ViewHolder(view)
}

// Replace the contents of a view (invoked by the layout manager)
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

    // Get element from your dataset at this position and replace the
    // contents of the view with that element
    viewHolder.textViewTitle.text = dataSet[position].title
    viewHolder.textViewBody.text = dataSet[position].body
}

override fun getItemCount() = dataSet.size
}

NotesActivity.kt

    adapter = NotesAdapter(mutableListOf())
    recyclerView.adapter = adapter

    adapter.setOnItemClickListener(object : NotesAdapter.ClickListener {
        override fun onItemClick(v: View, position: Int) {

            Log.i("test", "pos: $position")

            Toast.makeText(applicationContext, "pos: $position", Toast.LENGTH_SHORT)
        }
    })

adapter_note_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
android:layout_margin="4dp"
app:cardBackgroundColor="@color/colorBackroundBright"
app:cardCornerRadius="15dp">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp"
    android:paddingBottom="8dp">

    <TextView
        android:id="@+id/textViewTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="title"
        android:textColor="@color/colorText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textViewBody"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:text="body"
        android:textColor="@color/colorText"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textViewTitle" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
BlazeCodeDev
  • 631
  • 1
  • 7
  • 27

1 Answers1

1

You just need to set your listener before you set your adapter to recycler.

Just change your code from

adapter = NotesAdapter(mutableListOf())
recyclerView.adapter = adapter

adapter.setOnItemClickListener(object : NotesAdapter.ClickListener {
    override fun onItemClick(v: View, position: Int) {

        Log.i("test", "pos: $position")

        Toast.makeText(applicationContext, "pos: $position", Toast.LENGTH_SHORT)
    }
})

to this

 adapter = NotesAdapter(mutableListOf())
 adapter.setOnItemClickListener(object : NotesAdapter.ClickListener {
    override fun onItemClick(v: View, position: Int) {

        Log.i("test", "pos: $position")

        Toast.makeText(applicationContext, "pos: $position", Toast.LENGTH_SHORT)
    }
})

recyclerView.adapter = adapter
newbie101
  • 65
  • 10
  • have you tried to declare clickListener in the constructor? – newbie101 Mar 11 '21 at 15:23
  • I guess there's something wrong in your viewholder init block, which affect the initialization of your itemview listener.Try to remove the if statement and just itemView.setOnClickListener(this) left. – newbie101 Mar 11 '21 at 15:49