Di postingan sebelumnya kita sudah mengenal komponen-komponen yang diperlukan untuk menggunakan RecyclerView. Selain itu kita juga membuat aplikasi sederhana yang menampilkan nama-nama negara. Di postingan kali ini kita akan membuat fungsi klik untuk setiap item yang ada. Ketika terjadi event klik, kita akan menampilkan nama negara dengan komponen toast.
Untuk membuat item yang ada di RecyclerView bisa menerima input klik dari user, kita perlu memasang click listener untuk item tersebut. Listener ini adalah implementasi dari interface ‘View.OnClickListener’.
Di sini kita perlu melakukan beberapa perubahan untuk class-class yang ada. Perubahan yang dilakukan ditandai dengan teks bold.
CountryViewHolder.kt
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_row_country.view.*
class CountryViewHolder(
view: View,
private val clickListener: ((Country) -> Unit)
) : RecyclerView.ViewHolder(view) {
fun bind(item: Country) = with(itemView) {
iv_country.setImageResource(item.image)
tv_country.text = item.name
setOnClickListener { clickListener(item) }
}
}
Kita menambah satu argument (clickListener) di constructor ViewHolder. ‘clickListener’ ini adalah lambda yang menerima objek ‘Country’.
Setelah itu kita memasang click listener dengan menggunakan method ‘setOnClickListener()’ di dalam block ‘with {}’ di method ‘bind()’. Karena block ‘with {}’ menerima argument ‘itemView’, maka method ‘setOnClickListener()’ dipanggil untuk objek ‘itemView’. ‘itemView’ ini adalah method yang disediakan class ViewHolder untuk mengambil root ViewGroup. Di dalam block ‘setOnClickListener {}’ kita memanggil lambda ‘clickListener’ dengan memberikan objek Country: item.
CountryAdapter.kt
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class CountryAdapter(
private val clickListener: ((Country) -> Unit)
) : RecyclerView.Adapter<CountryViewHolder>() {
private val mItems: MutableList<Country> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CountryViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_row_country, parent, false)
return CountryViewHolder(view, clickListener)
}
override fun getItemCount(): Int = mItems.size
override fun onBindViewHolder(holder: CountryViewHolder, position: Int) {
holder.bind(mItems[position])
}
fun submitItems(items: List<Country>) {
mItems.clear()
mItems.addAll(items)
notifyDataSetChanged()
}
}
Di sini kita juga perlu menambahkan argument dengan tipe lambda yang sama dengan yang digunakan di ViewHolder. Implementasi lambda ‘clickListener’ ini berada di Activity.
MainActivity.kt
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rv_country.layoutManager = LinearLayoutManager(this)
val adapter = CountryAdapter { country ->
Toast.makeText(this, country.name, Toast.LENGTH_SHORT).show()
}
rv_country.adapter = adapter
val items = listOf(
Country(image = R.drawable.ic_launcher_background, name = "Indonesia"),
Country(image = R.drawable.ic_launcher_background, name = "Vietnam"),
Country(image = R.drawable.ic_launcher_background, name = "Singapore"),
Country(image = R.drawable.ic_launcher_background, name = "Thailand"),
Country(image = R.drawable.ic_launcher_background, name = "Malaysia")
)
adapter.submitItems(items)
}
}
Di sini kita menambahkan implementasi lambda yang diperlukan Adapter. Di dalam block lambda ini kita menampilkan toast dengan nama negara untuk item yang menerima event click.
item_row_country.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:id="@+id/iv_country"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Country Image"
tools:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/tv_country"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:textSize="26sp"
android:textStyle="bold"
tools:text="Indonesia" />
</LinearLayout>
Kita juga menambahkan attribute background untuk LinearLayout (root ViewGroup) untuk memberikan efek ripple ketika item ini menerima event click.
Yuuup, kira-kira seperti itu cara menambahkan fungsi klik di RecyclerView. Thanks!
Source Code: https://github.com/bonioctavianus/android-recyclerview-example
Reference: https://developer.android.com/guide/topics/ui/layout/recyclerview