هذا الدرس التطبيقي حول الترميز هو جزء من دورة "أساسيات Android Kotlin". يمكنك تحقيق أقصى استفادة من هذه الدورة التدريبية إذا اتبعت ترتيب الخطوات في دروس البرمجة. يتم إدراج جميع الدروس التطبيقية حول الترميز الخاصة بالدورة التدريبية في الصفحة المقصودة للدروس التطبيقية حول الترميز في دورة Android Kotlin Fundamentals.
مقدمة
في هذا الدرس العملي، ستتعرّف على كيفية إضافة عنوان يمتد على عرض القائمة المعروضة في RecyclerView
. تستند هذه السلسلة إلى تطبيق Sleep Tracker من سلسلة الدروس البرمجية السابقة.
ما يجب معرفته
- كيفية إنشاء واجهة مستخدم أساسية باستخدام نشاط ولقطات وطرق عرض
- كيفية التنقّل بين الأجزاء وكيفية استخدام
safeArgs
لنقل البيانات بين الأجزاء - عرض النماذج وعوامل إنشاء النماذج وعمليات التحويل و
LiveData
والمراقبين المرتبطين بها - كيفية إنشاء قاعدة بيانات
Room
وإنشاء كائن وصول إلى البيانات (DAO) وتحديد الكيانات - كيفية استخدام الروتينات الفرعية للتفاعلات مع قاعدة البيانات والمهام الأخرى التي تستغرق وقتًا طويلاً
- كيفية تنفيذ
RecyclerView
أساسي باستخدامAdapter
وViewHolder
وتنسيق العناصر - كيفية تنفيذ ربط البيانات في
RecyclerView
- كيفية إنشاء واستخدام أدوات ربط البيانات لتحويل البيانات
- كيفية استخدام
GridLayoutManager
- كيفية تسجيل النقرات على العناصر في
RecyclerView.
والتعامل معها
أهداف الدورة التعليمية
- كيفية استخدام أكثر من
ViewHolder
معRecyclerView
لإضافة عناصر بتنسيق مختلف على وجه التحديد، كيفية استخدامViewHolder
ثانٍ لإضافة عنوان فوق العناصر المعروضة فيRecyclerView
الإجراءات التي ستنفذّها
- يمكنك الاستناد إلى تطبيق TrackMySleepQuality من الدرس التطبيقي السابق في هذه السلسلة.
- أضِف عنوانًا يمتد على عرض الشاشة فوق ليالي النوم المعروضة في
RecyclerView
.
يحتوي تطبيق تتبُّع النوم الذي تبدأ به على ثلاث شاشات، يتم تمثيلها بواسطة أجزاء، كما هو موضّح في الشكل أدناه.
تحتوي الشاشة الأولى، المعروضة على اليمين، على أزرار لبدء التتبُّع وإيقافه. تعرض الشاشة بعض بيانات نوم المستخدم. يؤدي النقر على الزر محو إلى حذف جميع البيانات التي جمعها التطبيق للمستخدم نهائيًا. الشاشة الثانية، المعروضة في المنتصف، مخصّصة لاختيار تقييم لجودة النوم. الشاشة الثالثة هي عرض تفصيلي يفتح عندما ينقر المستخدم على عنصر في الشبكة.
يستخدم هذا التطبيق بنية مبسطة تتضمّن وحدة تحكّم في واجهة المستخدم ونموذج عرض وLiveData
وقاعدة بيانات Room
لتخزين بيانات النوم بشكل دائم.
في هذا الدرس العملي، ستضيف عنوانًا إلى شبكة العناصر المعروضة. ستبدو شاشتك الرئيسية النهائية على النحو التالي:
يعلّمك هذا الدرس التطبيقي المبدأ العام لتضمين عناصر تستخدم تنسيقات مختلفة في RecyclerView
. أحد الأمثلة الشائعة هو تضمين عناوين في القائمة أو الشبكة. يمكن أن تحتوي القائمة على عنوان واحد لوصف محتوى العنصر. يمكن أن تحتوي القائمة أيضًا على عدة عناوين لتجميع العناصر وفصلها في قائمة واحدة.
لا تعرف RecyclerView
أي معلومات عن بياناتك أو نوع التنسيق الذي يتضمّنه كل عنصر. تعمل LayoutManager
على ترتيب العناصر على الشاشة، ولكنّ المحوّل يكيّف البيانات ليتم عرضها ويمرّر عناصر الحاوية إلى RecyclerView
. لذا، ستضيف الرمز لإنشاء العناوين في المحوّل.
طريقتان لإضافة العناوين
في RecyclerView
، يتوافق كل عنصر في القائمة مع رقم فهرس يبدأ من 0. على سبيل المثال:
[البيانات الفعلية] -> [طرق عرض المحوّل]
[0: SleepNight] -> [0: SleepNight]
[1: SleepNight] -> [1: SleepNight]
[2: SleepNight] -> [2: SleepNight]
إحدى طرق إضافة العناوين إلى قائمة هي تعديل المحوّل لاستخدام ViewHolder
مختلف من خلال التحقّق من الفهارس التي يجب عرض العنوان فيها. سيكون Adapter
مسؤولاً عن تتبُّع العنوان. على سبيل المثال، لعرض عنوان في أعلى الجدول، عليك عرض ViewHolder
مختلف للعنوان أثناء تخطيط العنصر ذي الفهرس الصفري. بعد ذلك، سيتم ربط جميع العناصر الأخرى بإزاحة العنوان، كما هو موضّح أدناه.
[البيانات الفعلية] -> [طرق عرض المحوّل]
[0: Header]
[0: SleepNight] -> [1: SleepNight]
[1: SleepNight] -> [2: SleepNight]
[2: SleepNight] -> [3: SleepNight.
هناك طريقة أخرى لإضافة العناوين وهي تعديل مجموعة البيانات الأساسية لشبكة البيانات. بما أنّ جميع البيانات التي يجب عرضها مخزّنة في قائمة، يمكنك تعديل القائمة لتضمين عناصر تمثّل عنوانًا. هذا النوع أسهل قليلاً في الفهم، ولكنّه يتطلّب منك التفكير في كيفية تصميم العناصر، حتى تتمكّن من دمج أنواع العناصر المختلفة في قائمة واحدة. عند تنفيذها بهذه الطريقة، ستعرض أداة الربط العناصر التي تم تمريرها إليها. وبالتالي، يكون العنصر في الموضع 0 عبارة عن عنوان، والعنصر في الموضع 1 عبارة عن SleepNight
، والذي يرتبط مباشرةً بما يظهر على الشاشة.
[البيانات الفعلية] -> [طرق عرض المحوّل]
[0: Header] -> [0: Header]
[1: SleepNight] -> [1: SleepNight]
[2: SleepNight] -> [2: SleepNight]
[3: SleepNight] -> [3: SleepNight]
ولكل منهجية مزايا وعيوب. لا يؤدي تغيير مجموعة البيانات إلى إدخال تغيير كبير على بقية رمز المحوّل، ويمكنك إضافة منطق العنوان من خلال تعديل قائمة البيانات. من ناحية أخرى، يمنح استخدام ViewHolder
مختلف من خلال التحقّق من الفهارس للعناوين المزيد من الحرية في تخطيط العنوان. ويتيح أيضًا للمحوّل التعامل مع كيفية تكييف البيانات مع طريقة العرض بدون تعديل البيانات الأساسية.
في هذا الدرس العملي، ستعدّل RecyclerView
لعرض عنوان في بداية القائمة. في هذه الحالة، سيستخدم تطبيقك ViewHolder
مختلفًا للعنوان عن ViewHolder
عناصر البيانات. سيتحقّق التطبيق من فهرس القائمة لتحديد ViewHolder
الذي سيتم استخدامه.
الخطوة 1: إنشاء فئة DataItem
لتجريد نوع العنصر والسماح للمحوّل بالتعامل مع "العناصر" فقط، يمكنك إنشاء فئة حامل بيانات تمثّل إما SleepNight
أو Header
. ستكون مجموعة البيانات بعد ذلك عبارة عن قائمة بعناصر حامل البيانات.
يمكنك الحصول على تطبيق المبتدئين من GitHub أو مواصلة استخدام تطبيق SleepTracker الذي أنشأته في الدرس العملي السابق.
- نزِّل الرمز RecyclerViewHeaders-Starter من GitHub. يحتوي الدليل RecyclerViewHeaders-Starter على الإصدار الأولي من تطبيق SleepTracker اللازم لهذا الدرس البرمجي. يمكنك أيضًا مواصلة العمل على تطبيقك المكتمل من الدرس العملي السابق إذا أردت ذلك.
- افتح الملف SleepNightAdapter.kt.
- أسفل فئة
SleepNightListener
، في المستوى الأعلى، حدِّد فئةsealed
باسمDataItem
تمثّل عنصر بيانات.
يحدّد الصفsealed
نوعًا مغلقًا، ما يعني أنّه يجب تحديد جميع الفئات الفرعية منDataItem
في هذا الملف. نتيجةً لذلك، يعرف المترجم عدد الفئات الفرعية. لا يمكن لجزء آخر من الرمز تحديد نوع جديد منDataItem
قد يؤدي إلى تعطُّل المحوّل البرمجي.
sealed class DataItem {
}
- داخل نص الفئة
DataItem
، حدِّد فئتين تمثّلان الأنواع المختلفة من عناصر البيانات. الأول هوSleepNightItem
، وهو عبارة عن غلاف حولSleepNight
، لذا يأخذ قيمة واحدة تُسمىsleepNight
. لجعلها جزءًا من الفئة المحكمة، يجب أن توسّعDataItem
.
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
- الفئة الثانية هي
Header
، لتمثيل عنوان. بما أنّ العنوان لا يتضمّن أي بيانات فعلية، يمكنك تعريفه على أنّهobject
. وهذا يعني أنّه لن يكون هناك سوى مثيل واحد منHeader
. كرِّر الخطوة السابقة لتمديدDataItem
.
object Header: DataItem()
- داخل
DataItem
، على مستوى الفئة، حدِّد السمةabstract
Long
باسمid
. عندما يستخدم المحوّل البرمجيDiffUtil
لتحديد ما إذا كان قد تم تغيير عنصر وكيفية تغييره، يجب أن يعرفDiffItemCallback
معرّف كل عنصر. سيظهر لك خطأ لأنّSleepNightItem
وHeader
يجب أن تتجاوزا السمة المجردةid
.
abstract val id: Long
- في
SleepNightItem
، استبدِلid
لعرضnightId
.
override val id = sleepNight.nightId
- في
Header
، استبدِلid
لعرضLong.MIN_VALUE
، وهو عدد صغير جدًا (أي -2 أس 63). وبالتالي، لن يتعارض هذا المعرّف أبدًا مع أيnightId
حالي.
override val id = Long.MIN_VALUE
- يجب أن يبدو الرمز البرمجي المكتمل على النحو التالي، ويجب أن يتم إنشاء تطبيقك بدون أخطاء.
sealed class DataItem {
abstract val id: Long
data class SleepNightItem(val sleepNight: SleepNight): DataItem() {
override val id = sleepNight.nightId
}
object Header: DataItem() {
override val id = Long.MIN_VALUE
}
}
الخطوة 2: إنشاء ViewHolder للعنوان
- أنشئ التصميم للعنوان في ملف جديد لمورد التصميم باسم header.xml يعرض
TextView
. لا يوجد أي شيء مثير للاهتمام في هذا، لذا إليك الرمز.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Sleep Results"
android:padding="8dp" />
- استخرِج
"Sleep Results"
إلى مورد سلسلة وسمِّهheader_text
.
<string name="header_text">Sleep Results</string>
- في ملف SleepNightAdapter.kt، داخل
SleepNightAdapter
، فوق الفئةViewHolder
، أنشئ فئةTextViewHolder
جديدة. تعمل هذه الفئة على تضخيم تنسيق textview.xml، وتعرض مثيلاً منTextViewHolder
. بما أنّك أجريت ذلك من قبل، إليك الرمز، وعليك استيرادView
وR
:
class TextViewHolder(view: View): RecyclerView.ViewHolder(view) {
companion object {
fun from(parent: ViewGroup): TextViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.header, parent, false)
return TextViewHolder(view)
}
}
}
الخطوة 3: تعديل SleepNightAdapter
بعد ذلك، عليك تعديل بيان SleepNightAdapter
. بدلاً من دعم نوع واحد فقط من ViewHolder
، يجب أن يكون قادرًا على استخدام أي نوع من عناصر العرض.
تحديد أنواع العناصر
- في
SleepNightAdapter.kt
، على المستوى الأعلى، أسفل عباراتimport
وفوقSleepNightAdapter
، حدِّد ثابتَين لأنواع العرض.
يجب أن يميّزRecyclerView
نوع عرض كل عنصر، حتى يتمكّن من تعيين عنصر نائب للعرض بشكل صحيح.
private val ITEM_VIEW_TYPE_HEADER = 0
private val ITEM_VIEW_TYPE_ITEM = 1
- داخل
SleepNightAdapter
، أنشئ دالة لتجاوزgetItemViewType()
لعرض العنوان أو الثابت الصحيح للعنصر استنادًا إلى نوع العنصر الحالي.
override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is DataItem.Header -> ITEM_VIEW_TYPE_HEADER
is DataItem.SleepNightItem -> ITEM_VIEW_TYPE_ITEM
}
}
تعديل تعريف SleepNightAdapter
- في تعريف
SleepNightAdapter
، عدِّل الوسيطة الأولى لـListAdapter
منSleepNight
إلىDataItem
. - في تعريف
SleepNightAdapter
، غيِّر الوسيط العام الثاني لـListAdapter
منSleepNightAdapter.ViewHolder
إلىRecyclerView.ViewHolder
. ستظهر لك بعض الأخطاء بشأن التعديلات الضرورية، ويجب أن يبدو عنوان الصف كما هو موضّح أدناه.
class SleepNightAdapter(val clickListener: SleepNightListener):
ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {
تعديل طريقة onCreateViewHolder()
- غيِّر توقيع
onCreateViewHolder()
لعرضRecyclerView.ViewHolder
.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
- وسِّع نطاق تنفيذ طريقة
onCreateViewHolder()
لاختبار عنصر العرض المناسب وإرجاعه لكل نوع من أنواع العناصر. يجب أن تبدو الطريقة المعدَّلة مثل الرمز البرمجي أدناه.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_VIEW_TYPE_HEADER -> TextViewHolder.from(parent)
ITEM_VIEW_TYPE_ITEM -> ViewHolder.from(parent)
else -> throw ClassCastException("Unknown viewType ${viewType}")
}
}
تعديل onBindViewHolder()
- غيِّر نوع المَعلمة
onBindViewHolder()
منViewHolder
إلىRecyclerView.ViewHolder
.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
- أضِف شرطًا لتعيين البيانات إلى عنصر نائب للعرض فقط إذا كان العنصر النائب
ViewHolder
.
when (holder) {
is ViewHolder -> {...}
- تحويل نوع العنصر الذي تعرضه
getItem()
إلىDataItem.SleepNightItem
يجب أن تبدو دالةonBindViewHolder()
المكتملة على النحو التالي.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
val nightItem = getItem(position) as DataItem.SleepNightItem
holder.bind(nightItem.sleepNight, clickListener)
}
}
}
تعديل عمليات معاودة الاتصال diffUtil
- غيِّر الطرق في
SleepNightDiffCallback
لاستخدام فئةDataItem
الجديدة بدلاً منSleepNight
. يمكنك إيقاف تحذير lint كما هو موضّح في الرمز البرمجي أدناه.
class SleepNightDiffCallback : DiffUtil.ItemCallback<DataItem>() {
override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem.id == newItem.id
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem == newItem
}
}
إضافة العنوان وإرساله
- داخل
SleepNightAdapter
، أسفلonCreateViewHolder()
، عرِّف الدالةaddHeaderAndSubmitList()
كما هو موضّح أدناه. تأخذ هذه الدالة قائمةSleepNight
. بدلاً من استخدامsubmitList()
، التي توفّرهاListAdapter
، لإرسال قائمتك، ستستخدم هذه الدالة لإضافة عنوان ثم إرسال القائمة.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
- داخل
addHeaderAndSubmitList()
، إذا كانت القائمة التي تم تمريرها هيnull
، يتم عرض رأس فقط، وإلا يتم إرفاق الرأس ببداية القائمة، ثم يتم إرسال القائمة.
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
submitList(items)
- افتح الملف SleepTrackerFragment.kt وغيِّر الاستدعاء إلى
submitList()
إلىaddHeaderAndSubmitList()
.
- شغِّل تطبيقك ولاحظ كيف يتم عرض العنوان كأول عنصر في قائمة عناصر النوم.
هناك مشكلتان يجب إصلاحهما في هذا التطبيق، إحداهما ظاهرة والأخرى غير ظاهرة.
- يظهر العنوان في أعلى يمين الصفحة، ولا يمكن تمييزه بسهولة.
- لا يهم كثيرًا بالنسبة إلى قائمة قصيرة ذات عنوان واحد، ولكن يجب عدم إجراء معالجة القوائم في
addHeaderAndSubmitList()
على سلسلة التعليمات الرئيسية لواجهة المستخدم. تخيَّل قائمة تحتوي على مئات العناصر وعدة عناوين ومنطقًا لتحديد مكان إدراج العناصر. يجب أن يتم تنفيذ هذا العمل في روتين فرعي.
تغيير addHeaderAndSubmitList()
لاستخدام إجراءات فرعية:
- في المستوى الأعلى داخل الفئة
SleepNightAdapter
، حدِّدCoroutineScope
باستخدامDispatchers.Default
.
private val adapterScope = CoroutineScope(Dispatchers.Default)
- في
addHeaderAndSubmitList()
، شغِّل روتينًا فرعيًا فيadapterScope
لتعديل القائمة. بعد ذلك، انتقِل إلى سياقDispatchers.Main
لإرسال القائمة، كما هو موضّح في الرمز أدناه.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {
adapterScope.launch {
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
withContext(Dispatchers.Main) {
submitList(items)
}
}
}
- يجب أن يتم إنشاء الرمز وتشغيله، ولن تلاحظ أي فرق.
في الوقت الحالي، يبلغ عرض العنوان عرض العناصر الأخرى في الشبكة نفسها، ويشغل مساحة واحدة أفقيًا وعموديًا. تتسع الشبكة بأكملها لثلاثة عناصر بعرض مدى واحد أفقيًا، لذا يجب أن يستخدم العنوان ثلاثة مدى أفقيًا.
لإصلاح عرض العنوان، عليك إخبار GridLayoutManager
بموعد توسيع البيانات على جميع الأعمدة. يمكنك إجراء ذلك من خلال ضبط SpanSizeLookup
على GridLayoutManager
. هذا هو عنصر الإعداد الذي تستخدمه GridLayoutManager
لتحديد عدد الأعمدة التي سيتم استخدامها لكل عنصر في القائمة.
- افتح SleepTrackerFragment.kt.
- ابحث عن الرمز الذي تحدّد فيه
manager
، بالقرب من نهايةonCreateView()
.
val manager = GridLayoutManager(activity, 3)
- أسفل
manager
، حدِّدmanager.spanSizeLookup
، كما هو موضّح. عليك إنشاءobject
لأنّsetSpanSizeLookup
لا تقبل lambda. لإنشاءobject
في Kotlin، اكتبobject : classname
، وفي هذه الحالةGridLayoutManager.SpanSizeLookup
.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
- قد يظهر لك خطأ في المترجم البرمجي لاستدعاء الدالة الإنشائية. إذا كان الأمر كذلك، افتح قائمة النية باستخدام
Option+Enter
(Mac) أوAlt+Enter
(Windows) لتطبيق استدعاء الدالة الإنشائية.
- بعد ذلك، سيظهر لك خطأ في
object
يفيد بأنّك بحاجة إلى تجاهل الطرق. ضَع المؤشر علىobject
، واضغط علىOption+Enter
(Mac) أوAlt+Enter
(Windows) لفتح قائمة "النوايا"، ثم تجاهِل الطريقةgetSpanSize()
.
- في نص الدالة
getSpanSize()
، أعِد حجم الامتداد المناسب لكل موضع. الموضع 0 لديه حجم مدى يبلغ 3، بينما المواضع الأخرى لديها حجم مدى يبلغ 1. يجب أن يبدو الرمز المكتمل على النحو التالي:
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int) = when (position) {
0 -> 3
else -> 1
}
}
- لتحسين مظهر العنوان، افتح header.xml وأضِف الرمز التالي إلى ملف التصميم header.xml.
android:textColor="@color/white_text_color"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@color/colorAccent"
- شغِّل تطبيقك. من المفترض أن يظهر بالشكل الموضّح في لقطة الشاشة أدناه.
تهانينا! لقد أنهيت الخطوات.
مشروع "استوديو Android": RecyclerViewHeaders
- العنوان هو بشكل عام عنصر يمتد على عرض القائمة ويعمل كعنوان أو فاصل. يمكن أن تحتوي القائمة على عنوان واحد لوصف محتوى العنصر، أو عناوين متعددة لتجميع العناصر وفصلها عن بعضها البعض.
- يمكن أن يستخدم
RecyclerView
عناصر متعددة لعرض المحتوى لاستيعاب مجموعة غير متجانسة من العناصر، مثل العناوين وعناصر القائمة. - إحدى طرق إضافة العناوين هي تعديل المحوّل لاستخدام
ViewHolder
مختلف من خلال التحقّق من الفهارس التي يجب عرض العنوان فيها. يكونAdapter
مسؤولاً عن تتبُّع العنوان. - هناك طريقة أخرى لإضافة العناوين وهي تعديل مجموعة البيانات الأساسية (القائمة) لجدول البيانات، وهو ما فعلته في هذا الدرس التطبيقي.
في ما يلي الخطوات الرئيسية لإضافة عنوان صفحة:
- جرِّد البيانات في قائمتك من خلال إنشاء
DataItem
يمكنه الاحتفاظ بعناوين أو بيانات. - أنشِئ عنصر نائب للعرض يتضمّن تصميمًا للعنوان في المحوّل.
- عدِّل المحوّل وطُرق استخدامه لاستخدام أي نوع من
RecyclerView.ViewHolder
. - في
onCreateViewHolder()
، أعِد النوع الصحيح من عنصر العرض الخاص بعنصر البيانات. - عدِّل
SleepNightDiffCallback
ليتوافق مع الصفDataItem
. - أنشئ دالة
addHeaderAndSubmitList()
تستخدم إجراءات فرعية متزامنة لإضافة العنوان إلى مجموعة البيانات، ثم استدعِsubmitList()
. - نفِّذ
GridLayoutManager.SpanSizeLookup()
لجعل العنوان فقط بعرض ثلاث مساحات.
دورة Udacity التدريبية:
مستندات مطوّري تطبيقات Android:
يسرد هذا القسم مهامًا منزلية محتملة للطلاب الذين يعملون على هذا الدرس التطبيقي العملي كجزء من دورة تدريبية يقودها مدرّب. على المعلّم تنفيذ ما يلي:
- حدِّد واجبًا منزليًا إذا لزم الأمر.
- توضيح كيفية إرسال الواجبات المنزلية للطلاب
- وضع درجات للواجبات المنزلية
يمكن للمدرّبين استخدام هذه الاقتراحات بالقدر الذي يريدونه، ويجب ألا يترددوا في تكليف الطلاب بأي واجبات منزلية أخرى يرونها مناسبة.
إذا كنت تعمل على هذا الدرس العملي بنفسك، يمكنك استخدام مهام الواجب المنزلي هذه لاختبار معلوماتك.
الإجابة عن هذه الأسئلة
السؤال 1
أيّ من العبارات التالية صحيحة في ما يتعلّق بـ ViewHolder
؟
▢ يمكن للمحوّل استخدام فئات ViewHolder
متعددة لتضمين العناوين وأنواع مختلفة من البيانات.
▢ يمكنك الحصول على عنصر تحكّم واحد فقط في العرض للبيانات، وعنصر تحكّم واحد في العرض للعنوان.
▢ يمكن أن يتوافق تنسيق RecyclerView
مع أنواع متعددة من العناوين، ولكن يجب أن تكون البيانات موحّدة.
▢ عند إضافة عنوان، عليك إنشاء فئة فرعية من RecyclerView
لإدراج العنوان في الموضع الصحيح.
السؤال 2
متى يجب استخدام الروتينات المشتركة مع RecyclerView
؟ اختَر كل العبارات الصحيحة.
▢ أبدًا RecyclerView
هو عنصر واجهة مستخدم ويجب ألا يستخدم إجراءات فرعية.
▢ استخدام إجراءات روتينية للمهام الطويلة التي قد تؤدي إلى إبطاء واجهة المستخدم
▢ يمكن أن تستغرق عمليات معالجة القوائم وقتًا طويلاً، ويجب دائمًا تنفيذها باستخدام إجراءات فرعية.
▢ استخدِم إجراءات روتينية مع دوال تعليق لتجنُّب حظر سلسلة التعليمات الرئيسية.
السؤال 3
أيّ مما يلي ليس عليك فعله عند استخدام أكثر من ViewHolder
؟
▢ في ViewHolder
، قدِّم ملفات تخطيط متعددة لتوسيعها حسب الحاجة.
▢ في onCreateViewHolder()
، أعِد النوع الصحيح من حاوية العرض لعنصر البيانات.
▢ في onBindViewHolder()
، لا تربط البيانات إلا إذا كان عنصر العرض هو النوع الصحيح من عناصر العرض لعنصر البيانات.
▢ تعميم توقيع فئة المحوّل البرمجي لقبول أي RecyclerView.ViewHolder
ابدأ الدرس التالي:
للحصول على روابط تؤدي إلى دروس تطبيقية أخرى في هذه الدورة التدريبية، اطّلِع على الصفحة المقصودة الخاصة بالدروس التطبيقية حول أساسيات Android Kotlin.