---
title: "طريقة أفضل للتعامل مع النقر على عناصر RecyclerView"
description: "هناك أساليب متعددة لتعيين OnClickListener لعنصر في RecyclerView. إليكم أحدها، وهو ما أعتبره أفضل ممارسة."
canonical: https://oozou.com/ar/blog/a-better-way-to-handle-click-action-in-a-recyclerview-item-60
locale: ar
date: 2020-06-30
author: "OOZOU Team"
---

# طريقة أفضل للتعامل مع النقر على عناصر RecyclerView

> هناك أساليب متعددة لتعيين OnClickListener لعنصر في RecyclerView. إليكم أحدها، وهو ما أعتبره أفضل ممارسة.

Published: 2020-06-30 · Author: OOZOU Team (Engineering) · 3 min read

تعيين **OnClickListener** لعناصر القائمة مهمة شائعة جدًا في تطوير تطبيقات Android، ولا بد أنكم تعرفونها جيدًا إن كنتم من مطوّري Android. ومع ذلك رأيت تطبيقات مختلفة لها من مطوّرين مختلفين. في الماضي، حين كنت لا أزال أستخدم Java، كنت أحتاج إلى interface تحدد سلوك مستمع النقر، كي أتعامل مع النقر داخل **Fragment** أو **Activity** باستخدام بيانات عنصر محدد في **RecyclerView**. وقد تبدو الـ interface على هذا النحو:

```java
public interface OnItemClickListener {
    void onItemClick(Model model);
}
```

أما الآن في عام 2020، فلدينا Kotlin، ويمكننا ببساطة استخدام **Lambda** لتحقيق السلوك نفسه الذي كنا نحققه بالـ interface في Java.
لنبدأ بالـ **RecyclerAdapter**. في الـ Recycler Adapter الخاص بنا، يستقبل الـ constructor دالة **Lambda** كمعامل. وتعمل هذه الـ **Lambda** كمستمع يحمل الـ model الذي سيُعرض في **Fragment/Activity.**

```kotlin
class AwesomeAdapter(
    private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<ViewHolder> {

    var data: List<Model> = ArrayList(0)
         set(value) {
             field = value
             notifyDataSetChanged()
         }
}
```

وهنا يأتي الجزء الذي رأيت المطوّرين ينفّذونه بطرق مختلفة. أين تظنون أنه ينبغي تعيين مستمع النقر لكل عنصر في RecyclerView؟ في **onBindViewHolder** أم في **onCreateViewHolder**؟
تعيين مستمع النقر في **onBindViewHolder** سهل، لأن الـ adapter يحتفظ بالقائمة ويمكننا الوصول إلى عناصر **data** مباشرةً عبر موقعها في **onBindViewHolder**:

```kotlin
override fun onBindViewHolder(
        holder: ViewHolder,
        position: Int
    ) {
        val item = data[position]
        holder.bind(item)
        holder.itemView.setOnClickListener { onItemClicked(item) }
    }
}
```

لكن في RecyclerView يُستدعى **onBindViewHolder** **في كل مرة** يُربط فيها الـ ViewHolder، فيُستدعى **setOnClickListener** معه أيضًا. لذلك يُفضَّل تعيين مستمع النقر في **onCreateViewHolder**، الذي لا يُستدعى إلا عند إنشاء الـ ViewHolder**.**وإليكم مخططًا للتنفيذ.

في صنف الـ Adapter، لا يملك **onCreateViewHolder** أي مرجع إلى الموقع، لذلك نحتاج إلى الرجوع إلى موقع عنصر RecyclerView عبر الحقل **adapterPosition** في صنف **ViewHolder**. وكما ترون، نمرّر Lambda أخرى إلى صنف الـ ViewHolder، كي نتمكن من الوصول إلى البيانات حسب موقعها في صنف الـ Adapter.

# في Fragment/Activity

هكذا نهيّئ الـ adapter مع مستمع النقر.

```kotlin
val adapter = AlbumAdapter {model -> 
   //The click action you want to perform.
}
```

# في صنف الـ Adapter

```kotlin
class ArtistAdapter(
    private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<ArtistViewHolder>() {

    var data: List<Model> = ArrayList(0)
        set(value) {
            field = value
            notifyDataSetChanged()
        }

    override fun onCreateViewHolder(parent: ViewGroup, type: Int): ArtistViewHolder {
        val viewHolder = LayoutInflater.from(parent.context).inflate(R.layout.viewholder_awesome, parent, false)
        return AwesomeViewHolder(viewHolder) {
            onItemClick(values[it])
        }
    }

    override fun getItemCount(): Int = data.size

    override fun onBindViewHolder(viewHolder: ArtistViewHolder, position: Int) {
        viewHolder.bind(data[position])
    }

}
```

**صنف الـ ViewHolder**

```kotlin
class ArtistViewHolder(
    view: View,
    onItemClicked: (Int) -> Unit
) : RecyclerView.ViewHolder(view) {
    init {
        itemView.setOnClickListener {
            onItemClicked(adapterPosition)
        }
    }

    fun bind(model: Model) {
        //bind data
    }
}
```

# الخلاصة
أرى أن تعيين مستمع النقر لعناصر RecyclerView في **onCreateViewHolder** أفضل ممارسة، لأنه يقلّل استدعاءات الدالة بشكل كبير مقارنةً بتعيينه في **onBindViewHolder**. لكن قد تتساءلون: هل هذا ضروري فعلًا؟ فتعيين مستمع النقر عملية صغيرة ولن تسبب مشكلة أداء تُذكر على أي حال. هذا صحيح، لكن تخيّلوا أن كل عنصر في RecyclerView أصبح أكثر تعقيدًا، كأن يحتوي على عدة إجراءات نقر، أو حتى حدث نقر مطوّل (long click). في هذه الحالة يصبح النهج الذي ذكرته في هذا المقال هو الأفضل.
وهذا كل شيء! شكرًا لقراءتكم.

# المصدر
\- صورة الغلاف: https://www.goodfon.com/wallpaper/chernyi-fon-ruki-soprikasaiutsia.html

---

Contact OOZOU: hello@oozou.com · +66 2544 0000 · https://oozou.com/ar/contact

More for AI agents: https://oozou.com/llms.txt · every page has a markdown twin at its URL plus ".md"
