‫Android Kotlin Fundamentals 07.5: Headers in RecyclerView

ה-codelab הזה הוא חלק מהקורס Android Kotlin Fundamentals. כדי להפיק את המרב מהקורס הזה, מומלץ לעבוד על ה-codelabs לפי הסדר. כל ה-codelab של הקורס מפורטים בדף הנחיתה של ה-codelab בנושא יסודות Kotlin ל-Android.

מבוא

ב-codelab הזה נסביר איך להוסיף כותרת שמשתרעת לרוחב הרשימה שמוצגת ב-RecyclerView. המשך של בניית אפליקציית מעקב השינה מ-codelabs קודמים.

מה שכדאי לדעת

  • איך לבנות ממשק משתמש בסיסי באמצעות פעילות, רכיבים ותצוגות.
  • איך לנווט בין פרגמנטים ואיך להשתמש ב-safeArgs כדי להעביר נתונים בין פרגמנטים.
  • אפשר לראות את המודלים, את מפעלי המודלים, את הטרנספורמציות ואת LiveData ואת האובזרברים שלהם.
  • איך יוצרים מסד נתונים של Room, יוצרים DAO ומגדירים ישויות.
  • איך משתמשים ב-coroutines לאינטראקציות עם מסדי נתונים ולמשימות אחרות שפועלות לאורך זמן.
  • איך מטמיעים RecyclerView בסיסי עם Adapter, ViewHolder ופריסת פריטים.
  • איך מטמיעים קשירת נתונים ב-RecyclerView.
  • איך יוצרים מתאמי קישור ומשתמשים בהם כדי לבצע טרנספורמציה של נתונים.
  • איך משתמשים ב-GridLayoutManager.
  • איך לתעד ולטפל בקליקים על פריטים בRecyclerView.

מה תלמדו

  • איך משתמשים ביותר מ-ViewHolder עם RecyclerView כדי להוסיף פריטים בפריסה שונה. בפרט, איך משתמשים ב-ViewHolder שני כדי להוסיף כותרת מעל הפריטים שמוצגים ב-RecyclerView.

הפעולות שתבצעו:

  • המשך פיתוח של אפליקציית TrackMySleepQuality מתוך ה-codelab הקודם בסדרה הזו.
  • מוסיפים כותרת שמשתרעת לרוחב המסך מעל הלילות שמוצגים ב-RecyclerView.

אפליקציית מעקב השינה שמתחילים איתה כוללת שלושה מסכים, שמיוצגים על ידי רכיבי Fragment, כמו שמוצג באיור שלמטה.

במסך הראשון, שמוצג בצד ימין, יש לחצנים להפעלה ולהפסקה של המעקב. במסך מוצגים חלק מנתוני השינה של המשתמש. הלחצן ניקוי מוחק באופן סופי את כל הנתונים שהאפליקציה אספה על המשתמש. במסך השני, שמוצג באמצע, בוחרים את דירוג איכות השינה. המסך השלישי הוא תצוגת פרטים שנפתחת כשהמשתמש מקיש על פריט ברשת.

האפליקציה הזו משתמשת בארכיטקטורה פשוטה עם בקר ממשק משתמש, מודל תצוגה ו-LiveData, ומסד נתונים Room כדי לשמור את נתוני השינה.

ב-codelab הזה מוסיפים כותרת לרשת הפריטים שמוצגת. המסך הראשי הסופי ייראה כך:

ב-codelab הזה נלמד את העיקרון הכללי של הכללת פריטים שמשתמשים בפריסות שונות ב-RecyclerView. דוגמה נפוצה היא שימוש בכותרות ברשימה או ברשת. לרשימה יכולה להיות כותרת אחת שמתארת את תוכן הפריט. רשימה יכולה לכלול גם כמה כותרות כדי לקבץ ולהפריד בין פריטים ברשימה אחת.

RecyclerView לא יודע דבר על הנתונים שלכם או על סוג הפריסה של כל פריט. ‫LayoutManager מסדר את הפריטים במסך, אבל המתאם מעבד את הנתונים כדי להציג אותם ומעביר את מחזיקי התצוגה אל LayoutManager.RecyclerView לכן, תוסיפו את הקוד ליצירת כותרות במתאם.

שתי דרכים להוספת כותרות

ב-RecyclerView, כל פריט ברשימה תואם למספר אינדקס שמתחיל מ-0. לדוגמה:

[Actual Data] -> [Adapter Views]

‫[0: SleepNight] -> [0: SleepNight]

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

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

דרך אחת להוסיף כותרות לרשימה היא לשנות את המתאם כך שישתמש ב-ViewHolder אחר על ידי סימון אינדקסים שבהם צריך להציג את הכותרת. ה-Adapter יהיה אחראי למעקב אחרי הכותרת. לדוגמה, כדי להציג כותרת בראש הטבלה, צריך להחזיר ViewHolder שונה לכותרת בזמן הפריסה של הפריט עם האינדקס אפס. לאחר מכן, כל הפריטים האחרים ימופו עם ההיסט של הכותרת, כמו שמוצג בהמשך.

[Actual Data] -> [Adapter Views]

[0: Header]

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

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

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

דרך נוספת להוסיף כותרות היא לשנות את מערך הנתונים הבסיסי של טבלת הנתונים. מכיוון שכל הנתונים שצריך להציג מאוחסנים ברשימה, אפשר לשנות את הרשימה כך שתכלול פריטים שייצגו כותרת. השיטה הזו קצת יותר פשוטה להבנה, אבל היא מחייבת לחשוב על עיצוב האובייקטים כדי שאפשר יהיה לשלב את סוגי הפריטים השונים ברשימה אחת. אם מטמיעים את המתאם בצורה הזו, הוא יציג את הפריטים שמועברים אליו. לכן, הפריט במיקום 0 הוא כותרת, והפריט במיקום 1 הוא SleepNight, שמוצג ישירות על המסך.

[Actual Data] -> [Adapter Views]

[0: Header] -> [0: Header]

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

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

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

לכל מתודולוגיה יש יתרונות וחסרונות. שינוי מערך הנתונים לא משפיע על שאר קוד המתאם, ואפשר להוסיף לוגיקה של כותרות על ידי שינוי רשימת הנתונים. מצד שני, שימוש ב-ViewHolder אחר על ידי בדיקת אינדקסים של כותרות מאפשר יותר חופש בפריסת הכותרת. המתאם גם מאפשר לטפל באופן שבו הנתונים מותאמים לתצוגה בלי לשנות את נתוני הבסיס.

ב-codelab הזה, מעדכנים את RecyclerView כדי להציג כותרת בתחילת הרשימה. במקרה כזה, האפליקציה תשתמש ב-ViewHolder שונה לכותרת ולפריטי הנתונים. האפליקציה תבדוק את האינדקס של הרשימה כדי לקבוע באיזה ViewHolder להשתמש.

שלב 1: יוצרים מחלקה DataItem

כדי להפשיט את סוג הפריט ולאפשר למתאם להתמודד רק עם 'פריטים', אפשר ליצור מחזיק נתונים שמייצג SleepNight או Header. מערך הנתונים יהיה רשימה של פריטים של בעלי נתונים.

אפשר להוריד את אפליקציית המתחילים מ-GitHub, או להמשיך להשתמש באפליקציית SleepTracker שיצרתם בסדנת הקוד הקודמת.

  1. מורידים את הקוד RecyclerViewHeaders-Starter מ-GitHub. הספרייה RecyclerViewHeaders-Starter מכילה את גרסת ההתחלה של אפליקציית SleepTracker שנדרשת ל-codelab הזה. אם רוצים, אפשר גם להמשיך לעבוד על האפליקציה שסיימתם ליצור בסדנת הקוד הקודמת.
  2. פותחים את הקובץ SleepNightAdapter.kt.
  3. מתחת לכיתה SleepNightListener, ברמה העליונה, מגדירים כיתה sealed בשם DataItem שמייצגת פריט נתונים.

    מחלקת sealed מגדירה סוג סגור, כלומר כל מחלקות המשנה של DataItem חייבות להיות מוגדרות בקובץ הזה. כתוצאה מכך, מספר מחלקות המשנה ידוע לקומפיילר. חלק אחר בקוד לא יכול להגדיר סוג חדש של DataItem שעלול לשבור את המתאם.
sealed class DataItem {

 }
  1. בתוך הגוף של המחלקה DataItem, מגדירים שתי מחלקות שמייצגות את הסוגים השונים של פריטי הנתונים. הראשון הוא SleepNightItem, שהוא wrapper סביב 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: יצירת ViewHolder לכותרת

  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. ב-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, הוא צריך להיות מסוגל להשתמש בכל סוג של מחזיק תצוגה.

הגדרת סוגי הפריטים

  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
        }
    }

עדכון ההגדרה של SleepNightAdapter

  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}")
        }
    }

עדכון של onBindViewHolder()

  1. שינוי סוג הפרמטר של onBindViewHolder() מ-ViewHolder ל-RecyclerView.ViewHolder.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
  1. מוסיפים תנאי כדי להקצות נתונים לבעל התצוגה רק אם הבעלים הוא ViewHolder.
        when (holder) {
            is ViewHolder -> {...}
  1. מבצעים המרה (cast) של סוג האובייקט שמוחזר על ידי 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)
            }
        }
    }

עדכון של קריאות חוזרות (callbacks) של diffUtil

  1. משנים את השיטות ב-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
    }
}

הוספה ושליחה של הכותרת

  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. הקוד אמור להיבנות ולפעול, ולא תראו הבדל.

בשלב הזה, רוחב הכותרת זהה לרוחב של שאר הפריטים ברשת, והיא תופסת טווח אחד אופקית ואנכית. כל הרשת מתאימה לשלושה פריטים ברוחב של span אחד לרוחב, ולכן הכותרת צריכה להשתמש בשלושה spans לרוחב.

כדי לתקן את רוחב הכותרת, צריך לציין ל-GridLayoutManager מתי להרחיב את הנתונים על פני כל העמודות. כדי לעשות את זה, צריך להגדיר את SpanSizeLookup ב-GridLayoutManager. זהו אובייקט הגדרה שרכיב GridLayoutManager משתמש בו כדי לקבוע כמה תגי span יש להשתמש בהם לכל פריט ברשימה.

  1. פותחים את SleepTrackerFragment.kt.
  2. מחפשים את הקוד שבו מוגדר manager, לקראת סוף onCreateView().
val manager = GridLayoutManager(activity, 3)
  1. מתחת ל-manager, מגדירים את manager.spanSizeLookup, כמו שמוצג. צריך ליצור object כי setSpanSizeLookup לא מקבל lambda. כדי ליצור object ב-Kotlin, מקלידים object : classname, במקרה הזה GridLayoutManager.SpanSizeLookup.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
  1. יכול להיות שתקבלו שגיאת קומפילציה כדי לקרוא לבונה. אם כן, פותחים את תפריט הכוונות באמצעות Option+Enter (Mac) או Alt+Enter (Windows) כדי להחיל את קריאת הבונה.
  1. לאחר מכן תופיע שגיאה ב-object עם הודעה שצריך לבטל את השיטות. מציבים את הסמן על object, מקישים על Option+Enter (ב-Mac) או על Alt+Enter (ב-Windows) כדי לפתוח את תפריט הכוונות, ואז משנים את השיטה getSpanSize().
  1. בגוף של getSpanSize(), מחזירים את גודל הטווח הנכון לכל מיקום. המיקום 0 הוא בגודל 3, ושאר המיקומים הם בגודל 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 Studio: ‏ RecyclerViewHeaders

  • כותרת היא בדרך כלל פריט שמשתרע לרוחב הרשימה ומשמש ככותרת או כמפריד. רשימה יכולה לכלול כותרת אחת שמתארת את תוכן הפריט, או כמה כותרות שמקבצות פריטים ומפרידות ביניהם.
  • RecyclerView יכול להשתמש בכמה מחזיקי תצוגה כדי להכיל קבוצה הטרוגנית של פריטים, למשל כותרות ופריטים ברשימה.
  • דרך אחת להוסיף כותרות היא לשנות את המתאם כך שישתמש ב-ViewHolder אחר על ידי בדיקת האינדקסים שבהם צריך להציג את הכותרת. ה-Adapter אחראי למעקב אחרי הכותרת.
  • דרך נוספת להוסיף כותרות היא לשנות את מערך הנתונים הבסיסי (הרשימה) של רשת הנתונים, כמו שעשיתם ב-codelab הזה.

אלה השלבים העיקריים להוספת כותרת:

  • כדי להפוך את הנתונים ברשימה למופשטים, יוצרים DataItem שיכול להכיל כותרת או נתונים.
  • יוצרים מחזיק תצוגה עם פריסה לכותרת במתאם.
  • מעדכנים את המתאם ואת השיטות שלו כדי להשתמש בכל סוג של RecyclerView.ViewHolder.
  • ב-onCreateViewHolder(), מחזירים את הסוג הנכון של מחזיק התצוגה עבור פריט הנתונים.
  • צריך לעדכן את SleepNightDiffCallback כדי לעבוד עם הכיתה DataItem.
  • יוצרים פונקציית addHeaderAndSubmitList() שמשתמשת ב-coroutines כדי להוסיף את הכותרת למערך הנתונים, ואז קוראת ל-submitList().
  • מטמיעים את GridLayoutManager.SpanSizeLookup() כדי שהכותרת תהיה ברוחב של שלוש תגי span בלבד.

קורס ב-Udacity:

מסמכי תיעוד למפתחי Android:

בקטע הזה מפורטות אפשרויות למשימות ביתיות לתלמידים שעובדים על ה-Codelab הזה כחלק מקורס בהנחיית מדריך. המורה צריך:

  • אם צריך, מקצים שיעורי בית.
  • להסביר לתלמידים איך להגיש מטלות.
  • בודקים את שיעורי הבית.

אנשי ההוראה יכולים להשתמש בהצעות האלה כמה שרוצים, ומומלץ להם להקצות כל שיעורי בית אחרים שהם חושבים שמתאימים.

אם אתם עובדים על ה-codelab הזה לבד, אתם יכולים להשתמש במשימות האלה כדי לבדוק את הידע שלכם.

עונים על השאלות הבאות

שאלה 1

איזו מההצהרות הבאות נכונה לגבי ViewHolder?

‫▢ מתאם יכול להשתמש בכמה מחלקות ViewHolder כדי להכיל כותרות וסוגים שונים של נתונים.

‫▢ יכול להיות לכם בדיוק מחזיק תצוגה אחד לנתונים ומחזיק תצוגה אחד לכותרת.

‫▢ RecyclerView תומך בכמה סוגים של כותרות, אבל הנתונים צריכים להיות אחידים.

‫▢ כשמוסיפים כותרת, יוצרים מחלקת משנה של RecyclerView כדי להוסיף את הכותרת במיקום הנכון.

שאלה 2

מתי כדאי להשתמש בקורוטינות עם RecyclerView? צריך לבחור את כל ההצהרות הנכונות.

‫▢ אף פעם. RecyclerView הוא רכיב בממשק המשתמש, ולכן אסור להשתמש בו ברוטינות משנה.

‫▢ שימוש בקורוטינות למשימות לטווח ארוך שעלולות להאט את ממשק המשתמש.

‫▢ פעולות על רשימות יכולות לקחת הרבה זמן, ותמיד צריך לבצע אותן באמצעות קורוטינות.

‫▢ משתמשים ב-coroutines עם פונקציות השהיה כדי להימנע מחסימה של ה-thread הראשי.

שאלה 3

איזו מהפעולות הבאות לא צריך לבצע כשמשתמשים ביותר מ-ViewHolder אחד?

‫▢ ב-ViewHolder, מספקים כמה קובצי פריסה להרחבה לפי הצורך.

‫▢ ב-onCreateViewHolder(), מחזירים את הסוג הנכון של מחזיק התצוגה עבור פריט הנתונים.

‫▢ ב-onBindViewHolder(), מתבצעת קשירת נתונים רק אם מחזיק התצוגה הוא הסוג הנכון של מחזיק התצוגה עבור פריט הנתונים.

‫▢ הכללה של חתימת המחלקה של המתאם כדי לקבל כל RecyclerView.ViewHolder.

עוברים לשיעור הבא: 8.1 קבלת נתונים מהאינטרנט

קישורים ל-codelabs אחרים בקורס הזה מופיעים בדף הנחיתה של ה-codelabs בנושא יסודות Android Kotlin.