Android Kotlin Fundamentals 07.5: العناوين في RecyclerView

يشكّل هذا الدرس التطبيقي جزءًا من الدورة التدريبية لأساسيات Android Kotlin. ستحصل على أقصى قيمة ممكنة من هذه الدورة التدريبية إذا كنت تستخدم الدروس التطبيقية حول الترميز بشكل متسلسل. يتم إدراج جميع الدروس التطبيقية حول ترميز الدورات التدريبية في الصفحة المقصودة لدروس الترميز Android Kotlin Fundamentals.

مقدمة

في هذا الدرس التطبيقي حول الترميز، تتعلّم كيفية إضافة عنوان يمتد ليشمل عرض القائمة المعروضة في RecyclerView. أنت تعتمد على تطبيق تتبُّع النوم من الدروس التطبيقية السابقة لترميز الرموز.

ما يجب معرفته

  • كيفية إنشاء واجهة مستخدم أساسية باستخدام النشاط والأجزاء والمشاهدات.
  • كيفية التنقّل بين الأجزاء وكيفية استخدام safeArgs لتمرير البيانات بين الأجزاء.
  • عرض النماذج وعرض مصانع النماذج والتحوّلات وLiveData ومراصدها.
  • كيفية إنشاء قاعدة بيانات Room وإنشاء داود والتعريف بالكيانات
  • كيفية استخدام الكوروتين للتفاعلات في قاعدة البيانات والمهام الأخرى الطويلة الأمد
  • كيفية تنفيذ 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: عنوان]

[0: SleepNight] -> [1: SleepNight]

[1: SleepNight] -> [2: SleepNight]

[2: SleepNight] -> [3: SleepNight.

هناك طريقة أخرى لإضافة الرؤوس وهي تعديل مجموعة البيانات الاحتياطية لشبكة البيانات. ونظرًا لتخزين جميع البيانات التي تحتاج إلى عرضها في قائمة، يمكنك تعديل القائمة لتضمين عناصر لتمثيل رأس ما. وعلى الرغم من أن هذه الطريقة أسهل في الفهم، إلا أنها تتطلب منك التفكير في كيفية تصميم العناصر، حتى تتمكن من الجمع بين أنواع العناصر المختلفة في قائمة واحدة. وعند تنفيذها بهذه الطريقة، سيعرض المحوّل العناصر التي تم تمريرها إليه. وبذلك يكون العنصر في الموضع 0 رأسًا، والعنصر في الموضع 1 هو SleepNight، والذي يتم ربطه مباشرةً بما يظهر على الشاشة.

[البيانات الفعلية] -> [مشاهدات المحوِّل]

[0: عنوان] -> [0: عنوان]

[1: SleepNight] -> [1: SleepNight]

[2: SleepNight] -> [2: SleepNight]

[3: SleepNight] -> [3: SleepNight]

لكل منهجية مزايا وعيوب. لا يؤدي تغيير مجموعة البيانات إلى إدخال تغيير كبير على بقية رموز المحوّل، ويمكنك إضافة منطق العنوان عن طريق التلاعب بقائمة البيانات. ومن ناحية أخرى، يؤدي استخدام علامة ViewHolder مختلفة من خلال التحقّق من فهارس العناوين إلى توفير المزيد من الحرية في تنسيق العنوان. كما تتيح للمحول التعامل مع كيفية تكييف البيانات مع طريقة العرض بدون تعديل البيانات الاحتياطية.

في هذا الدرس التطبيقي حول الترميز، عدِّل RecyclerView لعرض عنوان في بداية القائمة. وفي هذه الحالة، سيستخدم تطبيقك ViewHolder مختلفًا لكل عنوان من العناصر للبيانات. وسيتحقّق التطبيق من فهرس القائمة لتحديد ViewHolder التي سيتم استخدامها.

الخطوة 1: إنشاء صف DataItem

لملخص نوع العنصر والسماح للمحول بالتعامل مع "items" يمكنك إنشاء فئة لصاحب البيانات تمثل SleepNight أو Header. بعد ذلك، ستظهر مجموعة بياناتك في شكل قائمة بعناصر حامل البيانات.

يمكنك إما الحصول على تطبيق إجراء التفعيل من GitHub أو مواصلة استخدام تطبيق SleepTracker الذي أنشأته في الدرس التطبيقي السابق.

  1. نزِّل الرمز RecyclerViewHeaders-Starter من GitHub. يتضمّن الدليل RecyclerViewHeaders-Starter إصدار إجراء التفعيل من تطبيق SleepTracker اللازم لهذا الدرس التطبيقي حول الترميز. ويمكنك أيضًا المتابعة من خلال التطبيق المكتمل من الدرس التطبيقي السابق في حال كنت تفضّل ذلك.
  2. افتح SleepNightAdaptiveer.kt.
  3. أسفل الفئة SleepNightListener، في أعلى مستوى، حدِّد فئة sealed تُسمى DataItem تمثل عنصرًا من البيانات.

    تحدّد فئة sealed نوعًا مغلقًا، ما يعني أنه يجب تحديد جميع الفئات الفرعية للسمة DataItem في هذا الملف. ونتيجة لذلك، يُعدّ عدد الفئات الفرعية معروفًا للمحوِّل. ليس من الممكن بالنسبة إلى جزء آخر من الرمز تحديد نوع جديد من DataItem يمكن أن يؤدي إلى تلف المحوّل.
sealed class DataItem {

 }
  1. داخل نص الفئة DataItem، حدِّد فئتين تمثّلان الأنواع المختلفة من عناصر البيانات. الحقل الأول هو SleepNightItem، وهو برنامج تضمين حول SleepNight، لذلك يأخذ قيمة واحدة تُسمى sleepNight. لجعله جزءًا من الصف المغلق، اطلب منه تمديد DataItem.
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
  1. الفئة الثانية هي Header، لتمثيل رأس. ونظرًا لعدم وجود بيانات فعلية في العنوان، يمكنك الإعلان عنه باعتباره object. وهذا يعني أنّه سيكون هناك مثيل واحد فقط من Header. ومرة أخرى، يمكنك تمديد فترة DataItem.
object Header: DataItem()
  1. داخل DataItem، على مستوى الصف، حدِّد خاصية abstract Long بالاسم id. عند استخدام المحوّل لـ DiffUtil لتحديد ما إذا كان أحد العناصر قد تغيّر وكيفية حدوث ذلك، يحتاج DiffItemCallback إلى معرفة معرّف كل عنصر. سيظهر لك خطأ، لأن SleepNightItem وHeader بحاجة إلى إلغاء الخاصية التجريدية id.
abstract val id: Long
  1. في SleepNightItem، يجب إلغاء السمة id لعرض nightId.
override val id = sleepNight.nightId
  1. في Header، عليك تجاوز id لعرض Long.MIN_VALUE، وهو عدد قليل جدًا (حرفيًا، -2 إلى 63). لذلك، لن يتعارض هذا مطلقًا مع أي nightId في وجوده.
override val id = Long.MIN_VALUE
  1. ومن المفترض أن يظهر الرمز النهائي على النحو التالي، وسيتم إنشاء تطبيقك بدون أخطاء.
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: إنشاء صاحب عرض للرأس

  1. أنشئ تنسيقًا للعنوان في ملف مورد تنسيق جديد باسم 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" />
  1. عليك استخراج "Sleep Results" إلى مورد سلسلة وتسميته header_text.
<string name="header_text">Sleep Results</string>
  1. في SleepNightAdaptiveer.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: تعديل SleepNightAdaptiveer

بعد ذلك، عليك تحديث بيان SleepNightAdapter. بدلاً من إتاحة نوع واحد فقط من ViewHolder، يجب أن يكون قادرًا على استخدام أي نوع من حاصل المشاهدات.

تحديد أنواع العناصر

  1. في SleepNightAdapter.kt، في أعلى مستوى، تحت العبارات import وبأعلى SleepNightAdapter، حدِّد ثابتَين لنوعَي الملف الشخصي.

    يجب أن يميّز RecyclerView نوع الملف الشخصي لكل عنصر لكي يتمكّن من تعيين مالك ملف شخصي له بشكل صحيح.
    private val ITEM_VIEW_TYPE_HEADER = 0
    private val ITEM_VIEW_TYPE_ITEM = 1
  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
        }
    }

تعديل تعريف SleepNightAdaptiveer

  1. في تعريف SleepNightAdapter، عدِّل الوسيطة الأولى لـ ListAdapter من SleepNight إلى DataItem.
  2. في تعريف SleepNightAdapter، غيِّر الوسيطة العامة الثانية لـ ListAdapter من SleepNightAdapter.ViewHolder إلى RecyclerView.ViewHolder. ستظهر لك بعض الأخطاء عند إجراء التحديثات اللازمة، ومن المفترض أن يظهر عنوان الصف الدراسي أدناه.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {

تعديل onCreateViewholder()

  1. يجب تغيير توقيع onCreateViewHolder() لعرض RecyclerView.ViewHolder.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
  1. توسيع تنفيذ طريقة 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}")
        }
    }

تعديل فيBindViewholder()

  1. غيِّر نوع المعلَمة onBindViewHolder() من ViewHolder إلى RecyclerView.ViewHolder.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
  1. أضِف شرطًا لتخصيص البيانات لمالك العرض فقط في حال كان ViewHolder هو.
        when (holder) {
            is ViewHolder -> {...}
  1. بث نوع الكائن الذي يعرضه 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)
            }
        }
    }

تعديل استدعاءات الاختلافات

  1. غيِّر الطرق في SleepNightDiffCallback لاستخدام صف DataItem الجديد بدلاً من SleepNight. يمكنك منع ظهور تحذير الوبر كما هو موضّح في الرمز أدناه.
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
    }
}

إضافة العنوان وإرساله

  1. داخل SleepNightAdapter، أسفل onCreateViewHolder()، حدِّد الدالة addHeaderAndSubmitList() كما هو موضّح أدناه. تتضمّن هذه الدالة قائمة SleepNight. بدلاً من استخدام submitList()، المقدمة من قِبل ListAdapter، لإرسال قائمتك، يمكنك استخدام هذه الوظيفة لإضافة عنوان ثم إرسال القائمة.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
  1. داخل addHeaderAndSubmitList()، إذا كانت القائمة التي تم تمريرها هي null، يمكنك عرض عنوان فقط، أو إرفاق العنوان في رأس القائمة، ثم إرسال القائمة.
val items = when (list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
submitList(items)
  1. افتح SleepTrackerFragment.kt وغيِّر المكالمة إلى submitList() إلى addHeaderAndSubmitList().
  1. يمكنك تشغيل تطبيقك وملاحظة كيفية عرض رأسك كأول عنصر في قائمة عناصر النوم.

هناك أمران يجب إصلاحهما لهذا التطبيق، أحدهما مرئي ولا يتم إصلاحه.

  • ويظهر العنوان في أعلى يمين الصفحة، ولا يمكن تمييزه بسهولة.
  • لا يهم كثيرًا بالنسبة إلى القائمة المختصَرة التي تتضمن عنوانًا واحدًا، ولكن يجب عدم تنفيذ التلاعب بالقوائم في addHeaderAndSubmitList() على سلسلة محادثات واجهة المستخدم. تخيّل قائمة تتضمّن مئات العناصر والعناوين المتعددة والمنطق لتحديد الأماكن التي يجب إدراج العناصر فيها. هذا العمل ينتمي إلى كوروتين.

تغيير addHeaderAndSubmitList() لاستخدام الكوروتين:

  1. في المستوى الأعلى داخل الصف SleepNightAdapter، حدِّد CoroutineScope مع Dispatchers.Default.
private val adapterScope = CoroutineScope(Dispatchers.Default)
  1. في 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)
            }
        }
    }
  1. من المفترض أن يتم إنشاء الرمز وتشغيله، ولن تلاحظ أي فرق.

حاليًا، يكون رأس العرض هو نفسه عرض العناصر الأخرى على الشبكة، حيث يَشغل امتدادًا واحدًا أفقيًا ورأسيًا. تتناسب الشبكة بالكامل مع ثلاثة عناصر بعرض واحد أفقيًا، لذا يجب أن يستخدم العنوان ثلاثة امتدادات أفقيًا.

لتصحيح عرض العنوان، عليك إخبار GridLayoutManager بوقت تمديد البيانات على جميع الأعمدة. ويمكنك إجراء ذلك من خلال إعداد SpanSizeLookup على GridLayoutManager. هذا كائن إعداد يستخدمه GridLayoutManager لتحديد عدد الامتدادات التي سيتم استخدامها لكل عنصر في القائمة.

  1. افتَح SleepTrackerFragment.kt.
  2. ابحث عن الرمز الذي تحدّده manager في نهاية onCreateView().
val manager = GridLayoutManager(activity, 3)
  1. أسفل manager، حدِّد manager.spanSizeLookup على النحو الموضّح. عليك إجراء object لأن setSpanSizeLookup لا يأخذ مصابيح حامية. لإنشاء object باللغة Kotlin، اكتب object : classname، في هذه الحالة GridLayoutManager.SpanSizeLookup.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
  1. قد يظهر لك خطأ في برنامج التجميع لطلب طريقة الإنشاء. في هذه الحالة، افتح قائمة intent مع Option+Enter (Mac) أو Alt+Enter (Windows) لتطبيق استدعاء دالة الإنشاء.
  1. بعد ذلك، ستظهر لك رسالة خطأ على object تفيد بأنه عليك إلغاء الطرق. ضع المؤشر على object، واضغط على Option+Enter (نظام التشغيل Mac) أو Alt+Enter (نظام التشغيل Windows) لفتح قائمة الأهداف، ثم ألغِ الطريقة getSpanSize().
  1. في نص getSpanSize()، اعرض حجم الامتداد المناسب لكل موضع. الموضع 0 له حجم امتداد 3، أما المواضع الأخرى، فحجمه يتراوح بين 1 و1. ويجب أن يظهر الرمز الكامل على النحو التالي:
    manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int) =  when (position) {
                0 -> 3
                else -> 1
            }
        }
  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"
  1. شغِّل تطبيقك. ومن المفترض أن يظهر لقطة الشاشة أدناه.

تهانينا. لقد أنهيت جميع الخطوات.

مشروع "استوديو 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.

بدء الدرس التالي: 8.1 الحصول على البيانات من الإنترنت

وللحصول على روابط إلى دروس تطبيقية أخرى حول الترميز في هذه الدورة التدريبية، يُرجى الاطّلاع على الصفحة المقصودة لتطبيق الدروس التطبيقية حول الترميز Kotlin Fundamentals.