Daha Doğru Yöntemler: RecyclerView Item Click
Kas 03, 2021hamurcuabi
2 Yorum
RecyclerView, Android dünyasındaki en popüler View'lerden biridir.. Bugün size bir öğeye tıklamak için daha iyi bir yaklaşım göstermek istiyorum. Kotlin kullanıyoruz ve kullanmıyorsanız kullanmalısınız😎 Yazımin ingilizcesine linke tıkayarak ulaşabilirsin.
En popüler yol
Tecrübelerime göre, gördüğüm en popüler yol Interface oluşturmak ve bunu adapter tarafına geçirmek. Ardından adapter tarafından alınır ve OnBindViewHolder içinde çağırım yapılır.
Çok şükür Kotlin'imiz var ve Java'da interface sınıfına sahip olmakla aynı davranışı elde etmek için Lambda'yı kullanabiliriz. Bu yüzden Interface kullanmayı unutun ve kodlamaya Adapter ile başlayalım!
class MyAwesomeAdapter(
private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<ViewHolder> {
var data: List<Model> = ArrayList(0)
set(value) {
field = value
notifyDataSetChanged()
}
}
En popüler yere geldik.Bu işin yapılacağı en basit yer aslında burası. Elimizde data var position var daha ne isteyelim.
override fun onBindViewHolder(
holder: ViewHolder,
position: Int
) {
val item = data[position]
holder.bind(item)
holder.itemView.setOnClickListener { onItemClicked(item) }
}
}
Fakat bu yaklaşımda bir performans sorunu var. RecyclerView'da, ViewHolder her bağlandığında onBindViewHolder çağrılır ve setOnClickListener da tetiklenir. Bu da büyük listelerde ya da karmaşık Adapter'larda performans kaybına yol açacaktır.
Daha İyi bir yaklaşım
onCreateViewHolder'da yalnızca bir ViewHolder oluşturulduğunda setOnClickListener ayarlasak aslında yeterli olacaktır.
Peki bize bir position lazım nasıl olcak bu iş diyebilirsiniz ama ViewHolder sınıfında absoluteAdapterPosition diye bir kurtarıcımız var.
Kodu göster de rahatlayalım artık diyor gibisin 🧐
Fragment ya da Activity
val adapter = UserAdapter {model ->
//Tıklanınca burası tetiklenir
}
Adapter
class UserAdapter(
private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<UserViewHolder>() {
var data: List<Model> = ArrayList(0)
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, type: Int): UserViewHolder {
val viewHolder = LayoutInflater.from(parent.context).inflate(R.layout.viewholder_user, parent, false)
return UserViewHolder(viewHolder) {
// Buraya dikkat
onItemClick(values[it])
}
}
override fun getItemCount(): Int = data.size
override fun onBindViewHolder(viewHolder: UserViewHolder, position: Int) {
viewHolder.bind(data[position])
}
}
ViewHolder
class UserViewHolder(
view: View,
onItemClicked: (Int) -> Unit
) : RecyclerView.ViewHolder(view) {
init {
itemView.setOnClickListener {
// Buraya dikkat sadece init edildiğinde çağırılıyor
onItemClicked(absoluteAdapterPosition)
}
}
fun bind(model: Model) {
//datayı işle
}
}
Kodlar bu kadar. Bu yeni yaklaşımı uygulamak ve kullanmak gayet basit. Bundan sonra RecyclerView'lerini daha performanslı olsun, ter temiz kodlar sizinle olsun 👋
adapter bestpractice kotlin recyclerview