Daha Doğru Yöntemler: RecyclerView Item Click

Kas 03, 2021
hamurcuabi

2 Yorum
1796

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

Benzer Yazılar


Yorumlar


November 05, 202112:23 @Onurcem

Çok mantıklı ve doğru. Her bind işleminde tekrar tekrar setleme yapmak saçma gerçekten. Aydınlattın yeniden eyvallah :)


November 04, 202119:01 @Birisi

İlk okuduğumda farkı anlamamıştım. Şuan tam olarak anladım ve sana katılıyorum bu çok daha doğru bir yöntem eline sağlık💯