هذا الدرس التطبيقي حول الترميز هو جزء من دورة "أساسيات Android Kotlin". يمكنك تحقيق أقصى استفادة من هذه الدورة التدريبية إذا اتبعت ترتيب الخطوات في دروس البرمجة. يتم إدراج جميع الدروس التطبيقية حول الترميز الخاصة بالدورة التدريبية في الصفحة المقصودة للدروس التطبيقية حول الترميز في دورة Android Kotlin Fundamentals.
مقدمة
تتيح معظم التطبيقات التي تستخدم القوائم والجداول التي تعرض العناصر للمستخدمين التفاعل مع العناصر. يُعد النقر على عنصر من قائمة والاطّلاع على تفاصيله حالة استخدام شائعة جدًا لهذا النوع من التفاعل. لتحقيق ذلك، يمكنك إضافة أدوات معالجة النقرات التي تستجيب لنقرات المستخدم على العناصر من خلال عرض تفاصيلها.
في هذا الدرس التطبيقي حول الترميز، ستضيف تفاعلاً إلى RecyclerView، استنادًا إلى إصدار موسّع من تطبيق "متتبّع النوم" من السلسلة السابقة من دروس الترميز التطبيقية.
ما يجب معرفته
- إنشاء واجهة مستخدم أساسية باستخدام نشاط وقِطع وعناصر عرض
- التنقّل بين الأجزاء واستخدام
safeArgsلنقل البيانات بين الأجزاء - عرض النماذج وعوامل إنشاء النماذج وعمليات التحويل و
LiveDataوالمراقبين المرتبطين بها - كيفية إنشاء قاعدة بيانات
Roomوإنشاء عنصر الوصول إلى البيانات (DAO) وتحديد الكيانات - كيفية استخدام الروتينات المشتركة لقاعدة البيانات والمهام الأخرى التي تستغرق وقتًا طويلاً
- كيفية تنفيذ
RecyclerViewأساسي باستخدامAdapterوViewHolderوتنسيق العناصر - كيفية تنفيذ ربط البيانات في
RecyclerView - كيفية إنشاء واستخدام أدوات ربط البيانات لتحويل البيانات
- كيفية استخدام
GridLayoutManager
أهداف الدورة التعليمية
- كيفية جعل العناصر في
RecyclerViewقابلة للنقر نفِّذ أداة معالجة نقرات للانتقال إلى عرض تفصيلي عند النقر على عنصر.
الإجراءات التي ستنفذّها
- استند إلى إصدار موسّع من تطبيق TrackMySleepQuality من الدرس العملي السابق ضمن هذه السلسلة.
- أضِف أداة معالجة نقرات إلى قائمتك وابدأ في الاستماع إلى تفاعل المستخدم. عند النقر على عنصر في القائمة، يتم بدء عملية الانتقال إلى جزء يتضمّن تفاصيل حول العنصر الذي تم النقر عليه. يوفر الرمز الأولي رمزًا لجزئية التفاصيل، بالإضافة إلى رمز التنقل.
يحتوي تطبيق تتبُّع النوم الأوّلي على شاشتَين، يتم تمثيلهما بلقطات، كما هو موضّح في الشكل أدناه.
|
|
تحتوي الشاشة الأولى، المعروضة على اليمين، على أزرار لبدء التتبُّع وإيقافه. تعرض الشاشة بعض بيانات نوم المستخدم. يؤدي النقر على الزر محو إلى حذف جميع البيانات التي جمعها التطبيق للمستخدم نهائيًا. الشاشة الثانية، المعروضة على اليسار، مخصّصة لاختيار تقييم لجودة النوم.
يستخدم هذا التطبيق بنية مبسطة تتضمّن وحدة تحكّم في واجهة المستخدم ونموذج عرض وLiveData وقاعدة بيانات Room للاحتفاظ ببيانات النوم.

في هذا الدرس العملي، ستضيف إمكانية الردّ عندما ينقر المستخدم على عنصر في الشبكة، ما يؤدي إلى ظهور شاشة تفاصيل مثل الشاشة أدناه. يتم توفير الرمز البرمجي لهذه الشاشة (الجزء ونموذج العرض والتنقّل) مع تطبيق البداية، وعليك تنفيذ آلية معالجة النقرات.

الخطوة 1: الحصول على تطبيق المبتدئين
- نزِّل رمز RecyclerViewClickHandler-Starter من GitHub وافتح المشروع في "استوديو Android".
- إنشاء تطبيق تتبُّع النوم الأوّلي وتشغيله
[اختياري] يمكنك تحديث تطبيقك إذا أردت استخدام التطبيق من الدرس العملي السابق.
إذا كنت ستستخدم تطبيقًا مبدئيًا متوفّرًا في GitHub لهذا الدرس العملي، انتقِل إلى الخطوة التالية.
إذا أردت مواصلة استخدام تطبيق تتبُّع النوم الذي أنشأته في الدرس العملي السابق، اتّبِع التعليمات أدناه لتعديل تطبيقك الحالي ليتضمّن الرمز البرمجي الخاص بقطعة الشاشة التفصيلية.
- حتى إذا كنت ستواصل استخدام تطبيقك الحالي، احصل على الرمز البرمجي RecyclerViewClickHandler-Starter من GitHub لتتمكّن من نسخ الملفات.
- انسخ جميع الملفات في حزمة
sleepdetail. - في المجلد
layout، انسخ الملفfragment_sleep_detail.xml. - انسخ المحتوى المعدَّل من
navigation.xml، والذي يضيف عناصر التنقّل الخاصة بـsleep_detail_fragment. - في حزمة
database، ضمنSleepDatabaseDao، أضِف طريقةgetNightWithId()الجديدة:
/**
* Selects and returns the night with given nightId.
*/
@Query("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
fun getNightWithId(key: Long): LiveData<SleepNight>- في
res/values/strings، أضِف مورد السلسلة التالي:
<string name="close">Close</string>- نظِّف تطبيقك وأعِد إنشاءه لتعديل ربط البيانات.
الخطوة 2: فحص الرمز لشاشة تفاصيل النوم
في هذا الدرس العملي، ستنفّذ معالج نقرات ينتقل إلى جزء يعرض تفاصيل حول ليلة النوم التي تم النقر عليها. يحتوي رمز التشغيل على الجزء ومخطط التنقّل الخاصين بـ SleepDetailFragment، لأنّه يتضمّن الكثير من الرموز، كما أنّ الأجزاء والتنقل ليسا جزءًا من هذا الدرس العملي. تعرَّف على الرمز التالي:
- في تطبيقك، ابحث عن حزمة
sleepdetail. تحتوي هذه الحزمة على الجزء ونموذج العرض وواجهة برمجة تطبيقات نموذج العرض لجزء يعرض تفاصيل ليلة واحدة من النوم. - في حزمة
sleepdetail، افتح الرمز البرمجي الخاص بـSleepDetailViewModelوافحصه. يأخذ نموذج العرض هذا المفتاح الخاص بـSleepNightوDAO في الدالة الإنشائية.
يتضمّن نص الفئة رمزًا برمجيًا للحصول علىSleepNightللمفتاح المحدّد، والمتغيّرnavigateToSleepTrackerللتحكّم في الرجوع إلىSleepTrackerFragmentعند الضغط على الزر إغلاق.
تعرض الدالةgetNightWithId()القيمةLiveData<SleepNight>ويتم تعريفها فيSleepDatabaseDao(في الحزمةdatabase). - في حزمة
sleepdetail، افتح الرمز البرمجي الخاص بـSleepDetailFragmentوافحصه. لاحظ إعداد ربط البيانات ونموذج العرض والمراقب الخاص بالتنقّل. - في حزمة
sleepdetail، افتح الرمز البرمجي الخاص بـSleepDetailViewModelFactory.
وافحصه. - في مجلد التنسيق، افحص
fragment_sleep_detail.xml. لاحظ المتغيّرsleepDetailViewModelالمعرَّف في العلامة<data>للحصول على البيانات التي سيتم عرضها في كل طريقة عرض من نموذج طريقة العرض.
يحتوي التصميم علىConstraintLayoutيتضمّنImageViewلجودة النوم وTextViewلتقييم الجودة وTextViewلمدة النوم وButtonلإغلاق جزء التفاصيل. - افتح ملف
navigation.xml. بالنسبة إلىsleep_tracker_fragment، لاحظ الإجراء الجديدaction_sleep_tracker_fragment_to_sleepDetailFragmentالذي تمّت إضافته إلىsleep_detail_fragment.
، وهو الانتقال من جزء "متتبّع النوم" إلى شاشة التفاصيل.
في هذه المهمة، ستعدّل RecyclerView للاستجابة لنقرات المستخدم من خلال عرض شاشة تفاصيل للعنصر الذي تم النقر عليه.
تتألف مهمة تلقّي النقرات والتعامل معها من جزأين: أولاً، عليك الاستماع إلى النقرة وتلقّيها وتحديد العنصر الذي تم النقر عليه. بعد ذلك، عليك الردّ على النقرة بإجراء.
إذًا، ما هو أفضل مكان لإضافة أداة معالجة نقرات لهذا التطبيق؟
- يستضيف
SleepTrackerFragmentالعديد من طرق العرض، لذا لن يخبرك الاستماع إلى أحداث النقر على مستوى الجزء بالعنصر الذي تم النقر عليه. ولن يخبرك حتى ما إذا كان العنصر الذي تم النقر عليه هو عنصر من العناصر أو أحد عناصر واجهة المستخدم الأخرى. - عند الاستماع على مستوى
RecyclerView، يصعب تحديد السلعة التي نقر عليها المستخدم في القائمة. - أفضل وتيرة للحصول على معلومات حول عنصر تم النقر عليه هي في الكائن
ViewHolder، لأنّه يمثّل عنصر قائمة واحدًا.
على الرغم من أنّ ViewHolder هو مكان رائع للاستماع إلى النقرات، إلا أنّه ليس المكان المناسب عادةً للتعامل معها. إذًا، ما هو أفضل مكان للتعامل مع النقرات؟
- تعرض
Adapterعناصر البيانات في طرق العرض، لذا يمكنك التعامل مع النقرات في المحوّل. ومع ذلك، فإنّ مهمة المحوّل هي تكييف البيانات لعرضها، وليس التعامل مع منطق التطبيق. - يجب عادةً التعامل مع النقرات في
ViewModel، لأنّViewModelيمكنه الوصول إلى البيانات والمنطق اللازمَين لتحديد الإجراء المطلوب اتّخاذه استجابةً للنقرة.
الخطوة 1: إنشاء أداة معالجة نقرات وتشغيلها من تخطيط العنصر
- في المجلد
sleeptracker، افتح SleepNightAdapter.kt. - في نهاية الملف، على المستوى الأعلى، أنشئ فئة مستمع جديدة،
SleepNightListener.
class SleepNightListener() {
}- داخل الفئة
SleepNightListener، أضِف الدالةonClick(). عند النقر على طريقة العرض التي تعرض عنصر قائمة، تستدعي طريقة العرض الدالةonClick()هذه. (ستضبط السمةandroid:onClickللعرض لاحقًا على هذه الدالة).
class SleepNightListener() {
fun onClick() =
}- أضِف وسيطة دالة
nightمن النوعSleepNightإلىonClick(). يعرف العرض العنصر الذي يعرضه، ويجب نقل هذه المعلومات للتعامل مع النقرة.
class SleepNightListener() {
fun onClick(night: SleepNight) =
}- لتحديد ما تفعله الدالة
onClick()، عليك تقديم دالة ردّ الاتصالclickListenerفي الدالة الإنشائية للفئةSleepNightListenerوتعيينها للدالةonClick().
يساعد منح دالة lambda التي تعالج النقرة اسمًا،clickListener، في تتبُّعها أثناء نقلها بين الفئات. لا يحتاج برنامجclickListenerإلىnight.nightIdللوصول إلى البيانات من قاعدة البيانات. يجب أن يبدوSleepNightListenerالصف المكتمل على النحو الموضّح في الرمز البرمجي أدناه.
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
fun onClick(night: SleepNight) = clickListener(night.nightId)
}- افتح list_item_sleep_night.xml.
- داخل الحظر
data، أضِف متغيّرًا جديدًا لإتاحة الفئةSleepNightListenerمن خلال ربط البيانات. امنح<variable>الجديدnameمنclickListener.اضبطtypeعلى الاسم المؤهّل بالكامل للفئةcom.example.android.trackmysleepquality.sleeptracker.SleepNightListener، كما هو موضّح أدناه. يمكنك الآن الوصول إلى الدالةonClick()فيSleepNightListenerمن هذا التصميم.
<variable
name="clickListener"
type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" />- للاستماع إلى النقرات على أي جزء من عنصر القائمة هذا، أضِف السمة
android:onClickإلىConstraintLayout.
اضبط السمة علىclickListener:onClick(sleep)باستخدام تعبير lambda لربط البيانات، كما هو موضّح أدناه:
android:onClick="@{() -> clickListener.onClick(sleep)}"الخطوة 2: تمرير أداة معالجة النقرات إلى عنصر حاوية العرض وعنصر الربط
- افتح الملف SleepNightAdapter.kt.
- عدِّل الدالة الإنشائية للفئة
SleepNightAdapterلتلقّيval clickListener: SleepNightListener. عندما يربط المحوّلViewHolder، سيحتاج إلى تزويده بوظيفة معالجة النقرات هذه.
class SleepNightAdapter(val clickListener: SleepNightListener):
ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {- في
onBindViewHolder()، عدِّل طلبholder.bind()لتمرير معالج النقر إلىViewHolderأيضًا. سيظهر لك خطأ في المترجم لأنّك أضفت مَعلمة إلى استدعاء الدالة.
holder.bind(getItem(position)!!, clickListener)- أضِف المَعلمة
clickListenerإلىbind(). لإجراء ذلك، ضَع المؤشر على الخطأ، واضغط علىAlt+Enter(في نظام التشغيل Windows) أوOption+Enter(في نظام التشغيل Mac) على الخطأ، كما هو موضّح في لقطة الشاشة أدناه.
- داخل الفئة
ViewHolder، داخل الدالةbind()، خصِّص أداة معالجة النقرات للكائنbinding. يظهر لك خطأ لأنّك بحاجة إلى تعديل عنصر الربط.
binding.clickListener = clickListener- لتعديل ربط البيانات، عليك تنظيف مشروعك ثم إعادة إنشائه. (قد تحتاج أيضًا إلى إبطال ذاكرات التخزين المؤقت). لذلك، أخذت أداة معالجة نقرات من دالة إنشاء المحوّل، ومرّرتها إلى حامل العرض وإلى كائن الربط.
الخطوة 3: عرض إشعار مؤقت عند النقر على عنصر
أصبح لديك الآن الرمز اللازم لتسجيل النقرة، ولكن لم تنفِّذ الإجراء الذي يحدث عند النقر على عنصر في القائمة. أبسط ردّ هو عرض إشعار مؤقت يعرض nightId عند النقر على عنصر. يؤكّد ذلك أنّه عند النقر على عنصر في القائمة، يتم تسجيل nightId الصحيح ونقله.
- افتح الملف SleepTrackerFragment.kt.
- في
onCreateView()، ابحث عن المتغيّرadapter. لاحظ أنّه يعرض خطأ، لأنّه يتوقّع الآن مَعلمة مستمع نقر. - حدِّد أداة معالجة نقرات من خلال تمرير تعبير لامدا إلى
SleepNightAdapter. تعرض دالة lambda البسيطة هذه إشعارًا مؤقتًا يعرضnightId، كما هو موضّح أدناه. عليك استيرادToast. في ما يلي التعريف الكامل المعدَّل.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})- شغِّل التطبيق، وانقر على العناصر، وتأكَّد من أنّها تعرض رسالة منبثقة تتضمّن
nightIdالصحيح. بما أنّ العناصر تتضمّن قيمnightIdمتزايدة، ويعرض التطبيق الليلة الأحدث أولاً، يظهر العنصر الذي يتضمّن أدنى قيمةnightIdفي أسفل القائمة.
في هذه المهمة، ستغيّر السلوك عند النقر على عنصر في RecyclerView، بحيث ينتقل التطبيق بدلاً من عرض إشعار مؤقت إلى جزء تفصيلي يعرض المزيد من المعلومات حول الليلة التي تم النقر عليها.
الخطوة 1: التنقّل عند النقر
في هذه الخطوة، بدلاً من عرض إشعار مؤقت فقط، يمكنك تغيير تعبير lambda الخاص بمعالج النقرات في onCreateView() من SleepTrackerFragment لتمرير nightId إلى SleepTrackerViewModel وتفعيل التنقّل إلى SleepDetailFragment.
حدِّد دالة معالجة النقرات:
- افتح الملف SleepTrackerViewModel.kt.
- داخل
SleepTrackerViewModel، بالقرب من النهاية، حدِّدonSleepNightClicked()دالة معالجة النقرات.
fun onSleepNightClicked(id: Long) {
}- داخل
onSleepNightClicked()، ابدأ التنقّل من خلال ضبط_navigateToSleepDetailعلىidالذي تم تمريره في ليلة النوم التي تم النقر عليها.
fun onSleepNightClicked(id: Long) {
_navigateToSleepDetail.value = id
}- تنفيذ
_navigateToSleepDetail. كما فعلت من قبل، حدِّدprivate MutableLiveDataلحالة التنقّل. ويجب أن يتضمّنvalيمكن الوصول إليه.
private val _navigateToSleepDetail = MutableLiveData<Long>()
val navigateToSleepDetail
get() = _navigateToSleepDetail- تحديد الطريقة التي سيتم استدعاؤها بعد أن ينتهي التطبيق من التنقّل أطلِق عليها اسم
onSleepDetailNavigated()واضبط قيمتها علىnull.
fun onSleepDetailNavigated() {
_navigateToSleepDetail.value = null
}أضِف الرمز التالي لاستدعاء معالج النقرات:
- افتح الملف SleepTrackerFragment.kt وانتقِل للأسفل إلى الرمز الذي ينشئ المحوّل ويحدّد
SleepNightListenerلعرض إشعار مؤقت.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})- أضِف الرمز التالي أسفل الإشعار المؤقت لاستدعاء معالج النقر،
onSleepNighClicked()، فيsleepTrackerViewModelعند النقر على عنصر. مرِّرnightId، لكي يعرف نموذج العرض ليلة النوم التي يجب الحصول عليها. سيؤدي ذلك إلى حدوث خطأ لأنّك لم تحدّد قيمةonSleepNightClicked()بعد. يمكنك الاحتفاظ بالإشعار أو وضع علامة تعليق عليه أو حذفه، كما تريد.
sleepTrackerViewModel.onSleepNightClicked(nightId)أضِف الرمز البرمجي لتتبُّع النقرات:
- افتح SleepTrackerFragment.kt.
- في
onCreateView()، فوق تعريفmanagerمباشرةً، أضِف الرمز البرمجي لمراقبةnavigateToSleepDetailLiveDataالجديد. عندما يتغيّرnavigateToSleepDetail، انتقِل إلىSleepDetailFragment، مع تمريرnight، ثم استدعِonSleepDetailNavigated()بعد ذلك. بما أنّك أجريت ذلك من قبل في تجربة عملية سابقة، إليك الرمز البرمجي:
sleepTrackerViewModel.navigateToSleepDetail.observe(this, Observer { night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepDetailFragment(night))
sleepTrackerViewModel.onSleepDetailNavigated()
}
})- نفِّذ الرمز، وانقر على عنصر، و ... يتعطّل التطبيق.
التعامل مع القيم الفارغة في أدوات ربط البيانات:
- أعِد تشغيل التطبيق في وضع تصحيح الأخطاء. انقر على عنصر، ثم فلتر السجلات لعرض الأخطاء. سيظهر تتبُّع تسلسل استدعاء الدوال البرمجية يتضمّن شيئًا مشابهًا لما يلي.
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter itemلسوء الحظ، لا يوضّح تتبُّع تسلسل استدعاء الدوال البرمجية مكان حدوث هذا الخطأ. من عيوب ربط البيانات أنّه قد يصعّب تصحيح أخطاء الرمز البرمجي. يتعطّل التطبيق عند النقر على عنصر، والرمز الجديد الوحيد هو رمز معالجة النقرة.
ومع ذلك، تبيّن أنّه باستخدام آلية معالجة النقرات الجديدة هذه، أصبح من الممكن الآن استدعاء أدوات ربط البيانات بقيمة null لـ item. على وجه الخصوص، عند بدء تشغيل التطبيق، تبدأ قيمة LiveData بالقيمة null، لذا عليك إضافة عمليات التحقّق من القيم الخالية إلى كل محوّل.
- في
BindingUtils.kt، لكل محوّل ربط، غيِّر نوع وسيطةitemإلى قيمة قابلة للتصغير، ثم لفّ النص البرمجي باستخدامitem?.let{...}. على سبيل المثال، سيبدو المحوّل لـsleepQualityStringعلى النحو التالي. غيِّر المحوّلات الأخرى بالطريقة نفسها.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight?) {
item?.let {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
}- شغِّل تطبيقك. انقر على عنصر، وسيتم فتح عرض تفصيلي.
مشروع "استوديو Android": RecyclerViewClickHandler.
لجعل العناصر في RecyclerView تستجيب للنقرات، أرفِق أدوات معالجة النقرات بعناصر القائمة في ViewHolder، وتعامل مع النقرات في ViewModel.
لجعل العناصر في RecyclerView تستجيب للنقرات، عليك إجراء ما يلي:
- أنشئ فئة مستمع تأخذ تعبير lambda وتعيّنه إلى دالة
onClick().
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
fun onClick(night: SleepNight) = clickListener(night.nightId)
}- اضبط أداة معالجة النقرات على العرض.
android:onClick="@{() -> clickListener.onClick(sleep)}"- مرِّر أداة معالجة النقرات إلى أداة إنشاء المحوّل، ثم إلى أداة عرض العناصر، وأضِفها إلى عنصر الربط.
class SleepNightAdapter(val clickListener: SleepNightListener):
ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()holder.bind(getItem(position)!!, clickListener)binding.clickListener = clickListener- في الجزء الذي يعرض طريقة العرض القابلة لإعادة الاستخدام، حيث تنشئ المحوّل، حدِّد أداة معالجة النقرات من خلال تمرير تعبير لامدا إلى المحوّل.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
sleepTrackerViewModel.onSleepNightClicked(nightId)
})- تنفيذ معالج النقرات في نموذج العرض بالنسبة إلى النقرات على عناصر القائمة، يؤدي ذلك عادةً إلى الانتقال إلى جزء تفاصيل.
دورة Udacity التدريبية:
مستندات مطوّري تطبيقات Android:
يسرد هذا القسم مهامًا منزلية محتملة للطلاب الذين يعملون على هذا الدرس التطبيقي العملي كجزء من دورة تدريبية يقودها مدرّب. على المعلّم تنفيذ ما يلي:
- حدِّد واجبًا منزليًا إذا لزم الأمر.
- توضيح كيفية إرسال الواجبات المنزلية للطلاب
- وضع درجات للواجبات المنزلية
يمكن للمدرّبين استخدام هذه الاقتراحات بالقدر الذي يريدونه، ويجب ألا يترددوا في تكليف الطلاب بأي واجبات منزلية أخرى يرونها مناسبة.
إذا كنت تعمل على هذا الدرس العملي بنفسك، يمكنك استخدام مهام الواجب المنزلي هذه لاختبار معلوماتك.
الإجابة عن هذه الأسئلة
السؤال 1
لنفترض أنّ تطبيقك يحتوي على RecyclerView يعرض سلعًا في قائمة تسوّق. يحدّد تطبيقك أيضًا فئة معالجة نقرات:
class ShoppingListItemListener(val clickListener: (itemId: Long) -> Unit) {
fun onClick(cartItem: CartItem) = clickListener(cartItem.itemId)
}كيف يمكنك إتاحة ShoppingListItemListener لربط البيانات؟ يُرجى اختيار فئة واحدة.
▢ في ملف التصميم الذي يحتوي على RecyclerView الذي يعرض قائمة التسوّق، أضِف متغيّر <data> لـ ShoppingListItemListener.
▢ في ملف التصميم الذي يحدّد تصميم صف واحد في قائمة التسوّق، أضِف متغيّر <data> لـ ShoppingListItemListener.
▢ في فئة ShoppingListItemListener، أضِف دالة لتفعيل ربط البيانات:
fun onBinding (cartItem: CartItem) {dataBindingEnable(true)}▢ في الفئة ShoppingListItemListener، داخل الدالة onClick()، أضِف طلبًا لتفعيل ربط البيانات:
fun onClick(cartItem: CartItem) = {
clickListener(cartItem.itemId)
dataBindingEnable(true)
}السؤال 2
أين تتم إضافة السمة android:onClick لجعل العناصر في RecyclerView تستجيب للنقرات؟ يُرجى اختيار جميع الإجابات المناسبة.
▢ في ملف التصميم الذي يعرض RecyclerView، أضِفه إلى <androidx.recyclerview.widget.RecyclerView>
▢ أضِفها إلى ملف التنسيق الخاص بعنصر في الصف. إذا كنت تريد أن يكون العنصر بأكمله قابلاً للنقر، أضِفه إلى العرض الرئيسي الذي يحتوي على العناصر في الصف.
▢ أضِفها إلى ملف التنسيق الخاص بعنصر في الصف. إذا كنت تريد أن يكون TextView واحد في العنصر قابلاً للنقر، أضِفه إلى <TextView>.
▢ أضِفها دائمًا إلى ملف التصميم الخاص بـ MainActivity.
ابدأ الدرس التالي:

