0Pricing
Android Academy · درس

أحداث النقر في RecyclerView

تعامَلوا مع نقرات العناصر والضغطات المطوّلة في RecyclerView، ومرّروا مستمعي النقر إلى adapters، وانتقلوا إلى شاشة التفاصيل عند النقر على عنصر.

أحداث النقر في RecyclerView درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 3 من أصل 6. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 6 دروس في المجموع.

جعل عناصر القائمة قابلة للنقر

لا يحتوي RecyclerView على مستمع نقر مدمج مثل ListView. بل تضيف مستمعي النقر داخل Adapter.

النمط الموصى به: مرّر lambda (إجراءً لاستدعائه) إلى مُنشئ Adapter. عند النقر على عنصر، يستدعي Adapter هذا الـlambda مع العنصر المحدد — وتتولى Activity معالجة ما يحدث بعد ذلك.

Adapter مع استدعاء النقر

أضف معامل lambda باسم onItemClick إلى Adapter:

class FruitAdapter(
    private val fruits: List<Fruit>,
    private val onItemClick: (Fruit) -> Unit
) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val tvName: TextView = view.findViewById(R.id.tvName)
        val tvCalories: TextView = view.findViewById(R.id.tvCalories)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_fruit, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val fruit = fruits[position]
        holder.tvName.text = fruit.name
        holder.tvCalories.text = "${fruit.calories} kcal"
        // Set click listener on the whole item
        holder.itemView.setOnClickListener {
            onItemClick(fruit)
        }
    }

    override fun getItemCount() = fruits.size
}

معالجة النقرات في Activity

في Activity، مرّر lambda ينتقل إلى شاشة التفاصيل:

val adapter = FruitAdapter(fruits) { fruit ->
    // Called when user taps a fruit
    val intent = Intent(this, FruitDetailActivity::class.java)
    intent.putExtra("FRUIT_NAME", fruit.name)
    intent.putExtra("FRUIT_CALORIES", fruit.calories)
    startActivity(intent)
}

binding.recyclerView.apply {
    this.adapter = adapter
    layoutManager = LinearLayoutManager(this@MainActivity)
}

استلام البيانات في شاشة التفاصيل

اقرأ extras في Activity الخاصة بالتفاصيل:

class FruitDetailActivity : AppCompatActivity() {

    private lateinit var binding: ActivityFruitDetailBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityFruitDetailBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val name = intent.getStringExtra("FRUIT_NAME") ?: "Unknown"
        val calories = intent.getIntExtra("FRUIT_CALORIES", 0)

        binding.tvDetailName.text = name
        binding.tvDetailCalories.text = "$calories kcal"
    }
}

DiffUtil للتحديثات الفعالة

عند تغير بيانات القائمة، لا تستدعِ notifyDataSetChanged() — فهي تعيد رسم كل شيء. استخدم DiffUtil بدلًا منها:

  • تحسب الحد الأدنى من الفروقات بين القائمتين القديمة والجديدة
  • تحرك العناصر التي تغيرت فقط
  • تحسن الأداء وتجربة المستخدم

الطريقة الحديثة هي ListAdapter الذي يستخدم DiffUtil تلقائيًا.

ListAdapter مع DiffUtil

وسّع ListAdapter للحصول على تحديثات تلقائية ومتحركة للقائمة:

class FruitAdapter(
    private val onItemClick: (Fruit) -> Unit
) : ListAdapter<Fruit, FruitAdapter.ViewHolder>(DIFF_CALLBACK) {

    companion object {
        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Fruit>() {
            override fun areItemsTheSame(old: Fruit, new: Fruit) =
                old.name == new.name
            override fun areContentsTheSame(old: Fruit, new: Fruit) =
                old == new  // data class equals()
        }
    }

    // ... ViewHolder and onCreateViewHolder same as before ...

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val fruit = getItem(position)  // use getItem(), not fruits[position]
        holder.tvName.text = fruit.name
        holder.itemView.setOnClickListener { onItemClick(fruit) }
    }
}

إرسال قوائم جديدة

باستخدام ListAdapter، حدّث القائمة باستدعاء submitList(). يتولى DiffUtil الحركة تلقائيًا:

// In Activity:
val adapter = FruitAdapter { fruit ->
    // handle click
}
binding.recyclerView.adapter = adapter

// Initial data
adapter.submitList(fruits)

// Later, update with new data (e.g. after filtering):
val filtered = fruits.filter { it.calories < 100 }
adapter.submitList(filtered)  // DiffUtil animates the change

الضغط المطوّل وقوائم السياق

يمكنك أيضًا الاستجابة للضغط المطوّل من خلال ضبط setOnLongClickListener في onBindViewHolder:

  • أعِد true من المستمع لاستهلاك الحدث
  • استخدمه لعرض مربع حوار للحذف أو التعديل
  • أو طبّق الحذف بالسحب باستخدام ItemTouchHelper

إضافة زخارف للعناصر

أضف فاصلًا مرئيًا بين عناصر القائمة باستخدام DividerItemDecoration:

binding.recyclerView.apply {
    adapter = fruitAdapter
    layoutManager = LinearLayoutManager(this@MainActivity)
    addItemDecoration(
        DividerItemDecoration(
            this@MainActivity,
            DividerItemDecoration.VERTICAL
        )
    )
}

اختبار سريع

ما الطريقة الموصى بها لمعالجة النقرات على العناصر في RecyclerView Adapter؟

مراجعة: النقرات في RecyclerView

يمكنك الآن إنشاء قوائم تفاعلية:

  • مرّر استدعاء lambda إلى مُنشئ Adapter
  • في onBindViewHolder، استدعِ holder.itemView.setOnClickListener
  • انتقل إلى شاشة التفاصيل بتمرير extras عبر Intent
  • استخدم ListAdapter مع DiffUtil للحصول على تحديثات سلسة ومتحركة
  • استدعِ submitList() لتحديث البيانات المعروضة

التالي: حفظ البيانات محليًا باستخدام SharedPreferences.

الأسئلة الشائعة

هل درس «أحداث النقر في RecyclerView» مجاني؟

نعم — نص درس «أحداث النقر في RecyclerView» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 6 دروس في المجموع.

ماذا ستتعلم في «أحداث النقر في RecyclerView»؟

تعامَلوا مع نقرات العناصر والضغطات المطوّلة في RecyclerView، ومرّروا مستمعي النقر إلى adapters، وانتقلوا إلى شاشة التفاصيل عند النقر على عنصر. تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 6.

كم من الوقت يستغرق درس «أحداث النقر في RecyclerView»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مجموعات Kotlin
  2. أساسيات RecyclerView
  3. أحداث النقر في RecyclerView
  4. SharedPreferences
  5. تفضيلات DataStore
  6. Adapters وDiffUtil
← العودة إلى Android Academy