OOZOU
تواصلوا معنا
العودة إلى المدونة

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

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

30 يونيو 2020
3 دقائق للقراءة
طريقة أفضل للتعامل مع النقر على عناصر RecyclerView

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

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

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

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:

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 مع مستمع النقر.

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

في صنف الـ Adapter

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

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

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

تصميم البرمجيات عملية ممتعة لكنها معقدة، تتطلب الإبداع والتفكير المنطقي ومهارات حل المشكلات.

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد