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

يتم عرض بيانات النوم في RecyclerView. في هذا الدرس التطبيقي حول الترميز، ستنشئ الجزء DiffUtil والجزء الخاص بربط البيانات في RecyclerView. بعد الانتهاء من هذا الدرس العملي، سيظل تطبيقك يبدو كما هو تمامًا، ولكنّه سيكون أكثر كفاءة وأسهل في التوسّع والصيانة.
يمكنك مواصلة استخدام تطبيق SleepTracker من الدرس العملي السابق، أو يمكنك تنزيل تطبيق RecyclerViewDiffUtilDataBinding-Starter من GitHub.
- إذا لزم الأمر، نزِّل تطبيق RecyclerViewDiffUtilDataBinding-Starter من GitHub وافتح المشروع في Android Studio.
- شغِّل التطبيق.
- افتح ملف
SleepNightAdapter.kt. - افحص الرمز البرمجي للتعرّف على بنية التطبيق. راجِع الرسم البياني أدناه للحصول على ملخّص حول استخدام
RecyclerViewمع نمط المحوّل لعرض بيانات النوم للمستخدم.

- من إدخال المستخدم، ينشئ التطبيق قائمة بعناصر
SleepNight. يمثّل كل عنصرSleepNightليلة نوم واحدة ومدتها وجودتها. - يحوّل
SleepNightAdapterقائمة عناصرSleepNightإلى تنسيق يمكن أن يستخدمهRecyclerViewويعرضه. - ينتج محوّل
SleepNightAdapterViewHoldersيحتوي على طرق العرض والبيانات والمعلومات الوصفية الخاصة بطريقة العرض القابلة لإعادة الاستخدام لعرض البيانات. - تستخدم
RecyclerViewSleepNightAdapterلتحديد عدد العناصر المطلوب عرضها (getItemCount())، كما تستخدمRecyclerViewonCreateViewHolder()وonBindViewHolder()للحصول على عناصر نائبة لعرض البيانات.
الطريقة notifyDataSetChanged() غير فعّالة
لإخبار RecyclerView بأنّ أحد العناصر في القائمة قد تغيّر ويجب تعديله، يستدعي الرمز الحالي notifyDataSetChanged() في SleepNightAdapter، كما هو موضّح أدناه.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}ومع ذلك، يشير notifyDataSetChanged() إلى أنّ القائمة بأكملها قد تكون غير صالحة.RecyclerView نتيجةً لذلك، تعيد السمة RecyclerView ربط كل عنصر في القائمة وإعادة رسمه، بما في ذلك العناصر غير المرئية على الشاشة. هذا الكثير من العمل غير الضروري. بالنسبة إلى القوائم الكبيرة أو المعقّدة، قد تستغرق هذه العملية وقتًا طويلاً بما يكفي لتتسبب في وميض الشاشة أو تقطّعها أثناء تنقّل المستخدم في القائمة.
لحلّ هذه المشكلة، يمكنك إخبار RecyclerView بالتغييرات التي تم إجراؤها بالضبط. يمكن لـ RecyclerView بعد ذلك تعديل طرق العرض التي تم تغييرها على الشاشة فقط.
تتضمّن RecyclerView واجهة برمجة تطبيقات شاملة لتعديل عنصر واحد. يمكنك استخدام notifyItemChanged() لإخبار RecyclerView بأنّ أحد العناصر قد تغيّر، ويمكنك استخدام دوال مشابهة للعناصر التي تتم إضافتها أو إزالتها أو نقلها. يمكنك إجراء كل ذلك يدويًا، ولكن ستكون هذه المهمة غير بسيطة وقد تتضمّن الكثير من الأكواد.
لحسن الحظ، هناك طريقة أفضل.
تتسم أداة DiffUtil بالكفاءة وتتولى عنك المهام الشاقة
يحتوي RecyclerView على فئة تُسمى DiffUtil، وهي مخصّصة لاحتساب الفروق بين قائمتَين. تأخذ DiffUtil قائمة قديمة وقائمة جديدة وتحدّد العناصر المختلفة بينهما. تعثر هذه الطريقة على العناصر التي تمت إضافتها أو إزالتها أو تغييرها. بعد ذلك، تستخدم خوارزمية تُعرف باسم Eugene W. خوارزمية الفرق بين مايرز لمعرفة الحد الأدنى لعدد التغييرات التي يجب إجراؤها من القائمة القديمة لإنشاء القائمة الجديدة
بعد أن يحدّد DiffUtil العناصر التي تم تغييرها، يمكن أن يستخدم RecyclerView هذه المعلومات لتعديل العناصر التي تم تغييرها أو إضافتها أو إزالتها أو نقلها فقط، ما يجعله أكثر كفاءة من إعادة إنشاء القائمة بأكملها.
في هذه المهمة، ستتم ترقية SleepNightAdapter لاستخدام DiffUtil من أجل تحسين RecyclerView لإجراء تغييرات على البيانات.
الخطوة 1: تنفيذ SleepNightDiffCallback
لاستخدام وظائف الفئة DiffUtil، عليك توسيع DiffUtil.ItemCallback.
- فتح "
SleepNightAdapter.kt" - أسفل تعريف الفئة الكامل لـ
SleepNightAdapter، أنشئ فئة جديدة ذات مستوى أعلى باسمSleepNightDiffCallbackتتضمّنDiffUtil.ItemCallback. مرِّرSleepNightكمعلَمة عامة.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}- ضَع المؤشر في اسم الفئة
SleepNightDiffCallback. - اضغط على
Alt+Enter(Option+Enterعلى جهاز Mac) واختَر تنفيذ الأعضاء. - في مربّع الحوار الذي يظهر، اضغط على Shift مع النقر بزر الماوس الأيسر لاختيار الطريقتَين
areItemsTheSame()وareContentsTheSame()، ثم انقر على حسنًا.
سيؤدي ذلك إلى إنشاء رموز صورية داخلSleepNightDiffCallbackللطريقتَين، كما هو موضّح أدناه. تستخدمDiffUtilهاتين الطريقتين لمعرفة كيفية تغيير القائمة والعناصر.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}- داخل
areItemsTheSame()، استبدِلTODOبالرمز الذي يختبر ما إذا كان العنصرانSleepNightاللذان تم تمريرهما،oldItemوnewItem، متطابقَين. إذا كانت العناصر تتضمّنnightIdنفسه، تكون هي نفسها، لذا يجب عرضtrue. بخلاف ذلك، أعِدfalse. تستخدمDiffUtilهذا الاختبار للمساعدة في معرفة ما إذا تمت إضافة عنصر أو إزالته أو نقله.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem.nightId == newItem.nightId
}- داخل
areContentsTheSame()، تحقَّق مما إذا كانoldItemوnewItemيحتويان على البيانات نفسها، أي ما إذا كانا متساويين. سيتحقّق هذا الاختبار من المساواة من جميع الحقول، لأنّSleepNightهو فئة بيانات. تحدّد فئاتDataتلقائيًاequalsوبعض الطرق الأخرى. إذا كانت هناك اختلافات بينoldItemوnewItem، يخبر هذا الرمزDiffUtilبأنّه تم تعديل العنصر.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}من الأنماط الشائعة استخدام RecyclerView لعرض قائمة تتغيّر. توفّر RecyclerView فئة محوّل، ListAdapter، تساعدك في إنشاء محوّل RecyclerView يستند إلى قائمة.
تتتبّع ListAdapter القائمة نيابةً عنك وتُعلم المحوّل عند تعديل القائمة.
الخطوة 1: تغيير المحوّل لتوسيع ListAdapter
- في الملف
SleepNightAdapter.kt، غيِّر توقيع الفئةSleepNightAdapterلتوسيعListAdapter. - إذا طُلب منك ذلك، استورِد
androidx.recyclerview.widget.ListAdapter. - أضِف
SleepNightكمعلَمة أولى إلىListAdapter، قبلSleepNightAdapter.ViewHolder. - أضِف
SleepNightDiffCallback()كمَعلمة إلى الدالة الإنشائية. سيستخدمListAdapterهذا لتحديد التغييرات التي تم إجراؤها في القائمة. يجب أن تبدو توقيعات فئةSleepNightAdapterالمكتملة كما هو موضّح أدناه.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {- داخل فئة
SleepNightAdapter، احذف الحقلdata، بما في ذلك الدالة الضابطة. لن تحتاج إليها بعد الآن، لأنّListAdapterيتتبّع القائمة نيابةً عنك. - احذف عملية الإلغاء الخاصة بـ
getItemCount()، لأنّListAdapterتنفّذ هذه الطريقة نيابةً عنك. - للتخلّص من الخطأ في
onBindViewHolder()، غيِّر المتغيّرitem. بدلاً من استخدامdataللحصول علىitem، استدعِ طريقةgetItem(position)التي يوفّرهاListAdapter.
val item = getItem(position)الخطوة 2: استخدام submitList() لإبقاء القائمة محدَّثة
يجب أن يوضّح الرمز البرمجي ListAdapter أنّه تتوفّر قائمة معدَّلة. توفّر ListAdapter طريقة تُسمى submitList() لإعلام ListAdapter بأنّه يتوفّر إصدار جديد من القائمة. عند استدعاء هذه الطريقة، تقارن ListAdapter القائمة الجديدة بالقائمة القديمة وترصد العناصر التي تمت إضافتها أو إزالتها أو نقلها أو تغييرها. بعد ذلك، ListAdapter تعدّل السلع المعروضة من خلال RecyclerView.
- فتح "
SleepTrackerFragment.kt" - في
onCreateView()، في أداة المراقبة علىsleepTrackerViewModel، ابحث عن الخطأ الذي تتم فيه الإشارة إلى المتغيّرdataالذي حذفْته. - استبدِل
adapter.data = itبمكالمة إلىadapter.submitList(it). يظهر الرمز المعدَّل أدناه.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})- شغِّل تطبيقك، وسيتم تشغيله بشكل أسرع، ولكن قد لا يكون ذلك ملحوظًا إذا كانت قائمتك صغيرة.
في هذه المهمة، ستستخدم الأسلوب نفسه المستخدَم في دروس البرمجة السابقة لإعداد ربط البيانات، وستتخلّص من طلبات findViewById().
الخطوة 1: إضافة ربط البيانات إلى ملف التنسيق
- افتح ملف التنسيق
list_item_sleep_night.xmlفي علامة التبويب نص. - ضَع المؤشر على العلامة
ConstraintLayoutواضغط علىAlt+Enter(Option+Enterعلى جهاز Mac). يتم فتح قائمة الإجراءات المقصودة (قائمة "الإصلاح السريع"). - اختَر التحويل إلى تنسيق ربط البيانات. يؤدي ذلك إلى تضمين التنسيق في
<layout>وإضافة علامة<data>في الداخل. - ارجع إلى أعلى الصفحة، إذا لزم الأمر، وفي علامة
<data>، عرِّف متغيّرًا باسمsleep. - اجعل
typeهو الاسم المؤهّل بالكامل لـSleepNight،com.example.android.trackmysleepquality.database.SleepNight. يجب أن تبدو علامة<data>المكتملة كما هو موضّح أدناه.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>- لفرض إنشاء العنصر
Binding، اختَر إنشاء > تنظيف المشروع، ثم اختَر إنشاء > إعادة إنشاء المشروع. (إذا كنت لا تزال تواجه مشاكل، اختَر ملف > إبطال ذاكرات التخزين المؤقت / إعادة التشغيل). تتم إضافة عنصر الربطListItemSleepNightBinding، بالإضافة إلى الرمز ذي الصلة، إلى الملفات التي تم إنشاؤها في المشروع.
الخطوة 2: إنشاء تخطيط العنصر باستخدام ربط البيانات
- فتح "
SleepNightAdapter.kt" - في الفئة
ViewHolder، ابحث عن الطريقةfrom(). - احذف تعريف المتغيّر
view.
الرمز المراد حذفه:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)- في المكان الذي كان فيه المتغيّر
view، حدِّد متغيّرًا جديدًا باسمbindingيعمل على تضخيم عنصر الربطListItemSleepNightBinding، كما هو موضّح أدناه. استورِد العنصر الرابط المطلوب.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)- في نهاية الدالة، بدلاً من عرض
view، اعرضbinding.
return ViewHolder(binding)- للتخلص من الخطأ، ضَع مؤشر الماوس على الكلمة
binding. اضغط علىAlt+Enter(Option+Enterعلى جهاز Mac) لفتح قائمة "النية".
- اختَر تغيير نوع المَعلمة itemView لدالة الإنشاء الأساسية للفئة ViewHolder إلى ListItemSleepNightBinding. يؤدي ذلك إلى تعديل نوع المَعلمة للفئة
ViewHolder.

- انتقِل للأعلى إلى تعريف الفئة
ViewHolderللاطّلاع على التغيير في التوقيع. يظهر لك خطأ فيitemView، لأنّك غيّرتitemViewإلىbindingفي الطريقةfrom().
في تعريف الفئةViewHolder، انقر بزر الماوس الأيمن على أحد مواضعitemViewواختَر Refactor (إعادة تصميم) > Rename (إعادة تسمية). غيِّر الاسم إلىbinding. - أضِف البادئة
valإلى مَعلمة الدالة الإنشائيةbindingلجعلها سمة. - في استدعاء الفئة الرئيسية،
RecyclerView.ViewHolder، غيِّر المَعلمة منbindingإلىbinding.root. يجب تمريرView، وbinding.rootهوConstraintLayoutالجذر في تخطيط العنصر. - يجب أن يبدو تعريف الفئة المكتمل على النحو الموضّح في الرمز البرمجي أدناه.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){يظهر لك أيضًا خطأ في طلبات findViewById()، وعليك إصلاح هذا الخطأ أولاً.
الخطوة 3: استبدال findViewById()
يمكنك الآن تعديل السمات sleepLength وquality وqualityImage لاستخدام العنصر binding بدلاً من findViewById().
- غيِّر عمليات التهيئة الخاصة بـ
sleepLengthوqualityStringوqualityImageلاستخدام طرق العرض الخاصة بالكائنbinding، كما هو موضّح أدناه. بعد ذلك، من المفترض ألّا يعرض الرمز أي أخطاء أخرى.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImageبعد وضع عنصر الربط، لن تحتاج إلى تحديد السمات sleepLength وquality وqualityImage على الإطلاق. سيخزّن DataBinding عمليات البحث مؤقتًا، لذا ليس من الضروري تعريف هذه الخصائص.
- انقر بزر الماوس الأيمن على أسماء المواقع
sleepLengthوqualityوqualityImage. اختَر إعادة تصميم > تضمين، أو اضغط علىControl+Command+N(Option+Command+Nعلى جهاز Mac).
- شغِّل تطبيقك. (قد تحتاج إلى تنظيف مشروعك وإعادة إنشائه إذا كان يتضمّن أخطاء).
في هذه المهمة، ستعمل على ترقية تطبيقك لاستخدام ربط البيانات مع أدوات ربط لتحديد البيانات في طرق العرض.
في درس برمجة سابق، استخدمت الفئة Transformations للحصول على LiveData وإنشاء سلاسل منسَّقة لعرضها في طرق عرض النصوص. ومع ذلك، إذا كنت بحاجة إلى ربط أنواع مختلفة أو أنواع معقّدة، يمكنك توفير أدوات ربط لتساعد ميزة "ربط البيانات" في استخدام هذه الأنواع. محوّلات الربط هي محوّلات تأخذ بياناتك وتكيّفها لتصبح شيئًا يمكن لربط البيانات استخدامه لربط طريقة عرض، مثل نص أو صورة.
ستنفّذ ثلاثة برامج ربط، واحد للصورة عالية الجودة، وواحد لكل حقل نصي. باختصار، لتحديد أداة ربط، عليك تحديد طريقة تأخذ عنصرًا وعرضًا، وإضافة التعليق التوضيحي @BindingAdapter إليها. في نص الدالة، يمكنك تنفيذ عملية التحويل. في Kotlin، يمكنك كتابة أداة ربط كدالة إضافة في فئة العرض التي تتلقّى البيانات.
الخطوة 1: إنشاء أدوات ربط البيانات
يُرجى العِلم أنّه عليك استيراد عدد من الصفوف في هذه الخطوة، ولن يتم تحديدها بشكل فردي.
- فتح "
SleepNightAdapater.kt" - داخل الفئة
ViewHolder، ابحث عن الطريقةbind()وذكِّر نفسك بما تفعله هذه الطريقة. ستأخذ الرمز الذي يحتسب قيمbinding.sleepLengthوbinding.qualityوbinding.qualityImage، وتستخدمه داخل المحوّل بدلاً من ذلك. (في الوقت الحالي، اترك الرمز كما هو، وسيتم نقله في خطوة لاحقة). - في حزمة
sleeptracker، أنشئ ملفًا باسمBindingUtils.ktوافتحه. - عرِّف دالة إضافة على
TextViewباسمsetSleepDurationFormatted، ومرِّرSleepNight. ستكون هذه الدالة هي المحوّل الخاص بك لاحتساب مدة النوم وتنسيقها.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}- في نص
setSleepDurationFormatted، اربط البيانات بطريقة العرض كما فعلت فيViewHolder.bind(). استدعِconvertDurationToFormatted()، ثم اضبطtextالخاص بـTextViewعلى النص المنسَّق. (بما أنّ هذه دالة إضافية فيTextView، يمكنك الوصول مباشرةً إلى السمةtext).
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)- لإعلام ميزة ربط البيانات بمحوّل الربط هذا، أضِف التعليق التوضيحي
@BindingAdapterإلى الدالة. - هذه الدالة هي أداة الربط للسمة
sleepDurationFormatted، لذا مرِّرsleepDurationFormattedكوسيطة إلى@BindingAdapter.
@BindingAdapter("sleepDurationFormatted")- يضبط المحوّل الثاني جودة النوم استنادًا إلى القيمة في العنصر
SleepNight. أنشئ دالة إضافة باسمsetSleepQualityString()فيTextView، وأدخِلSleepNight. - في النص الأساسي، اربط البيانات بطريقة العرض كما فعلت في
ViewHolder.bind(). اتّصِل بالرقمconvertNumericQualityToStringواضبطtext. - أضِف التعليق التوضيحي
@BindingAdapter("sleepQualityString")إلى الدالة.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}- يضبط محوّل ربط البيانات الثالث الصورة في عرض الصورة. أنشئ دالة الإضافة على
ImageView، واستدعِsetSleepImage، واستخدِم الرمز منViewHolder.bind()، كما هو موضّح أدناه.
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight) {
setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}الخطوة 2: تعديل SleepNightAdapter
- فتح "
SleepNightAdapter.kt" - احذف كل شيء في الطريقة
bind()، لأنّه يمكنك الآن استخدام ربط البيانات والمحوّلات الجديدة لإنجاز هذا العمل نيابةً عنك.
fun bind(item: SleepNight) {
}- داخل
bind()، عليك تعيين قيمةitemللنوم، لأنّك بحاجة إلى إخبار عنصر الربط بشأنSleepNightالجديد.
binding.sleep = item- أسفل هذا السطر، أضِف
binding.executePendingBindings(). هذه الدالة هي عملية تحسين تطلب من ميزة ربط البيانات تنفيذ أي عمليات ربط معلّقة على الفور. من المستحسن دائمًا استدعاءexecutePendingBindings()عند استخدام أدوات ربط البيانات فيRecyclerView، لأنّ ذلك قد يؤدي إلى تسريع عملية تحديد حجم طرق العرض قليلاً.
binding.executePendingBindings()الخطوة 3: إضافة عمليات الربط إلى تنسيق XML
- فتح "
list_item_sleep_night.xml" - في
ImageView، أضِف السمةappبالاسم نفسه لبرنامج ربط البيانات الذي يضبط الصورة. مرِّر المتغيّرsleep، كما هو موضّح أدناه.
ينشئ هذا الموقع الرابط بين طريقة العرض وعنصر الربط من خلال المحوّل. عندما تتم الإشارة إلىsleepImage، سيعدّل المحوّل البيانات منSleepNight.
app:sleepImage="@{sleep}"- كرِّر الخطوات نفسها مع طرق عرض النص
sleep_lengthوquality_string. عند الإشارة إلىsleepDurationFormattedأوsleepQualityString، ستعدّل المحوّلات البيانات منSleepNight.
app:sleepDurationFormatted="@{sleep}"app:sleepQualityString="@{sleep}"- شغِّل تطبيقك، وسيعمل بالطريقة نفسها التي كان يعمل بها من قبل. تتولّى أدوات ربط البيانات جميع مهام التنسيق وتعديل طرق العرض عند تغيُّر البيانات، ما يؤدي إلى تبسيط
ViewHolderومنح الرمز البرمجي بنية أفضل بكثير من ذي قبل.
لقد عرضت القائمة نفسها في التمارين القليلة الأخيرة. هذا التصميم مقصود، وهو يوضّح لك أنّ واجهة Adapter تتيح لك تصميم الرمز البرمجي بطرق مختلفة. كلما كانت التعليمات البرمجية أكثر تعقيدًا، ازدادت أهمية تصميمها بشكل جيد. في تطبيقات الإنتاج، يتم استخدام هذه الأنماط وغيرها مع RecyclerView. تعمل جميع الأنماط، ولكل منها مزاياه. يعتمد الخيار الذي تختاره على ما تريد إنشاءه.
تهانينا! في هذه المرحلة، تكون قد قطعت شوطًا كبيرًا نحو إتقان RecyclerView على Android.
مشروع استوديو Android: RecyclerViewDiffUtilDataBinding
DiffUtil:
- يحتوي
RecyclerViewعلى فئة تُسمىDiffUtil، وهي مخصّصة لاحتساب الفروق بين قائمتَين. - يحتوي
DiffUtilعلى فئة باسمItemCallBackيمكنك توسيعها لمعرفة الفرق بين قائمتَين. - في الفئة
ItemCallback، يجب إلغاء الطريقتَينareItemsTheSame()وareContentsTheSame().
ListAdapter:
- للحصول على بعض ميزات إدارة القوائم مجانًا، يمكنك استخدام الفئة
ListAdapterبدلاً منRecyclerView.Adapter. ومع ذلك، إذا كنت تستخدمListAdapter، عليك كتابة محوّل خاص بك للتصميمات الأخرى، ولهذا السبب يوضّح لك هذا الدرس التطبيقي كيفية إجراء ذلك. - لفتح قائمة الإجراءات المقترَحة في "استوديو Android"، ضَع المؤشر على أي عنصر من عناصر الرمز واضغط على
Alt+Enter(Option+Enterعلى جهاز Mac). تكون هذه القائمة مفيدة بشكل خاص لإعادة تصميم الرمز البرمجي وإنشاء نماذج أولية لتنفيذ الطرق. القائمة حساسة للسياق، لذا عليك وضع المؤشر في المكان الصحيح تمامًا للحصول على القائمة الصحيحة.
ربط البيانات:
- استخدِم ربط البيانات في تخطيط العنصر لربط البيانات بطرق العرض.
محولات الربط:
- كنت تستخدم
Transformationsسابقًا لإنشاء سلاسل من البيانات. إذا كنت بحاجة إلى ربط بيانات من أنواع مختلفة أو معقّدة، قدِّم أدوات ربط البيانات للمساعدة في استخدامها. - لتعريف أداة ربط، حدِّد طريقة تتضمّن عنصرًا وطريقة عرض، وأضِف تعليقًا توضيحيًا إلى الطريقة باستخدام
@BindingAdapter. في Kotlin، يمكنك كتابة أداة ربط البيانات كدالة إضافية فيView. مرِّر اسم السمة التي يكيّفها المحوّل. على سبيل المثال:
@BindingAdapter("sleepDurationFormatted")- في تنسيق XML، اضبط السمة
appبالاسم نفسه لبرنامج ربط البيانات. مرِّر متغيّرًا يتضمّن البيانات. على سبيل المثال:
.app:sleepDurationFormatted="@{sleep}"دورات Udacity التدريبية:
مستندات مطوّري تطبيقات Android:
- إنشاء قائمة باستخدام RecyclerView
RecyclerViewDiffUtil- مكتبة ربط البيانات
- برامج ربط البيانات
notifyDataSetChanged()Transformations
مراجع أخرى:
يسرد هذا القسم مهامًا منزلية محتملة للطلاب الذين يعملون على هذا الدرس التطبيقي العملي كجزء من دورة تدريبية يقودها مدرّب. على المعلّم تنفيذ ما يلي:
- حدِّد واجبًا منزليًا إذا لزم الأمر.
- توضيح كيفية إرسال الواجبات المنزلية للطلاب
- وضع درجات للواجبات المنزلية
يمكن للمدرّبين استخدام هذه الاقتراحات بالقدر الذي يريدونه، ويجب ألا يترددوا في تكليف الطلاب بأي واجبات منزلية أخرى يرونها مناسبة.
إذا كنت تعمل على هذا الدرس العملي بنفسك، يمكنك استخدام مهام الواجب المنزلي هذه لاختبار معلوماتك.
الإجابة عن هذه الأسئلة
السؤال 1
أيّ مما يلي ضروري لاستخدام DiffUtil؟ يُرجى اختيار جميع الإجابات المناسبة.
▢ وسِّع نطاق الفئة ItemCallBack.
▢ إلغاء areItemsTheSame()
▢ إلغاء areContentsTheSame()
▢ استخدِم ربط البيانات لتتبُّع الاختلافات بين العناصر.
السؤال 2
أيّ مما يلي ينطبق على أدوات ربط البيانات؟
▢ محوّل الربط هو دالة تمّت إضافة التعليق التوضيحي @BindingAdapter إليها.
▢ يتيح لك استخدام أداة ربط البيانات فصل تنسيق البيانات عن حاوية العرض.
▢ يجب استخدام RecyclerViewAdapter إذا كنت تريد استخدام أدوات ربط البيانات.
▢ Binding adapters هي حلّ جيد عندما تحتاج إلى تحويل بيانات معقّدة.
السؤال 3
متى يجب استخدام Transformations بدلاً من أداة ربط البيانات؟ يُرجى اختيار جميع الإجابات المناسبة.
▢ بياناتك بسيطة.
▢ أنت بصدد تنسيق سلسلة.
▢ قائمتك طويلة جدًا.
▢ لا يحتوي ViewHolder إلا على عرض واحد.
ابدأ الدرس التالي:

