‫Android Kotlin Fundamentals 07.4: אינטראקציה עם פריטים ב-RecyclerView

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

מבוא

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

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

מה שכדאי לדעת

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

מה תלמדו

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

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

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

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

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

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

ב-codelab הזה, מוסיפים את האפשרות להגיב כשמשתמש מקיש על פריט ברשת, וכתוצאה מכך מוצג מסך פרטים כמו זה שמופיע בהמשך. הקוד של המסך הזה (fragment, view model וניווט) מסופק עם אפליקציית המתחילים, ואתם תטמיעו את מנגנון הטיפול בלחיצות.

שלב 1: הורדת אפליקציית המתחילים

  1. מורידים את הקוד של RecyclerViewClickHandler-Starter מ-GitHub ופותחים את הפרויקט ב-Android Studio.
  2. פיתוח והרצה של אפליקציית מעקב השינה ההתחלתית.

[אופציונלי] מעדכנים את האפליקציה אם רוצים להשתמש באפליקציה מה-codelab הקודם

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

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

  1. גם אם אתם ממשיכים להשתמש באפליקציה הקיימת, כדאי להוריד את הקוד של RecyclerViewClickHandler-Starter מ-GitHub כדי שתוכלו להעתיק את הקבצים.
  2. מעתיקים את כל הקבצים בחבילה sleepdetail.
  3. בתיקייה layout, מעתיקים את הקובץ fragment_sleep_detail.xml.
  4. מעתיקים את התוכן המעודכן של navigation.xml, שכולל את הניווט אל sleep_detail_fragment.
  5. ב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>
  1. ב-res/values/strings מוסיפים את משאב המחרוזת הבא:
<string name="close">Close</string>
  1. מנקים את האפליקציה ובונים אותה מחדש כדי לעדכן את קישור הנתונים.

שלב 2: בודקים את הקוד של מסך פרטי השינה

ב-codelab הזה, מטמיעים click handler שמוביל אל fragment שמציג פרטים על הלילה של השינה שעליו לחצו. קוד המתחילים כבר מכיל את קטע הקוד וגרף הניווט של SleepDetailFragment, כי מדובר בכמות גדולה של קוד, וקטעי קוד וניווט לא נכללים ב-codelab הזה. כדאי להכיר את הקוד הבא:

  1. באפליקציה, מאתרים את חבילת sleepdetail. החבילה הזו מכילה את ה-fragment, את מודל התצוגה ואת מפעל מודל התצוגה של fragment שמציג פרטים על שינה בלילה אחד.

  2. בחבילה sleepdetail, פותחים את הקוד של SleepDetailViewModel ובודקים אותו. מודל התצוגה הזה מקבל את המפתח של SleepNight ואת DAO בבונה.

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

    הפונקציה getNightWithId() מחזירה LiveData<SleepNight> ומוגדרת ב-SleepDatabaseDao (בחבילה database).

  3. בחבילה sleepdetail, פותחים את הקוד של SleepDetailFragment ובודקים אותו. שימו לב להגדרה של קשירת הנתונים, מודל התצוגה וה-observer לניווט.

  4. בחבילה sleepdetail, פותחים את הקוד של SleepDetailViewModelFactory ובודקים אותו.

  5. בתיקיית הפריסה, בודקים את fragment_sleep_detail.xml. שימו לב למשתנה sleepDetailViewModel שמוגדר בתג <data> כדי שהנתונים יוצגו בכל תצוגה ממודל התצוגה.

    הפריסה מכילה ConstraintLayout שמכיל ImageView לאיכות השינה, TextView לדירוג האיכות, TextView למשך השינה ו-Button לסגירת קטע הפרטים.

  6. פותחים את הקובץ navigation.xml. במקרה של sleep_tracker_fragment, שימו לב לפעולה החדשה של sleep_detail_fragment.

    הפעולה החדשה, action_sleep_tracker_fragment_to_sleepDetailFragment, היא הניווט מהקטע של מעקב השינה למסך הפרטים.

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

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

אז איפה הכי כדאי להוסיף את מאזין הקליקים באפליקציה הזו?

  • SleepTrackerFragment מארח תצוגות רבות, ולכן האזנה לאירועי קליקים ברמת הפריט לא תאפשר לכם לדעת על איזה פריט לחצו. הוא אפילו לא יגיד לכם אם מדובר בפריט שעליו לחצו או באחד מרכיבי ממשק המשתמש האחרים.
  • כשמאזינים ברמה RecyclerView, קשה להבין בדיוק על איזה פריט ברשימה המשתמש לחץ.
  • הקצב הכי טוב לקבלת מידע על פריט אחד שנלחץ הוא באובייקט ViewHolder, כי הוא מייצג פריט אחד ברשימה.

ViewHolder הוא מקום מצוין להאזנה לקליקים, אבל בדרך כלל הוא לא המקום הנכון לטפל בהם. אז איפה הכי טוב לטפל בקליקים?

  • ה-Adapter מציג פריטי נתונים בתצוגות, כך שאפשר לטפל בקליקים במתאם. עם זאת, התפקיד של המתאם הוא להתאים את הנתונים לתצוגה, ולא לטפל בלוגיקה של האפליקציה.
  • בדרך כלל כדאי לטפל בקליקים ב-ViewModel, כי ל-ViewModel יש גישה לנתונים וללוגיקה שקובעים מה צריך לקרות בתגובה לקליק.

שלב 1: יצירת מאזין לקליקים והפעלתו מפריסת הפריט

  1. בתיקייה sleeptracker, פותחים את SleepNightAdapter.kt.
  2. בסוף הקובץ, ברמה העליונה, יוצרים מחלקה חדשה של מאזין, SleepNightListener.
class SleepNightListener() {
    
}
  1. בתוך המחלקה SleepNightListener, מוסיפים פונקציה onClick(). כשלוחצים על התצוגה שבה מוצג פריט רשימה, התצוגה קוראת לפונקציה onClick() הזו. (בהמשך תגדירו את המאפיין android:onClick של התצוגה המפורטת לפונקציה הזו).
class SleepNightListener() {
    fun onClick() = 
}
  1. מוסיפים ארגומנט לפונקציה night מסוג SleepNight אל onClick(). התצוגה יודעת איזה פריט היא מציגה, והמידע הזה צריך לעבור כדי לטפל בלחיצה.
class SleepNightListener() {
    fun onClick(night: SleepNight) = 
}
  1. כדי להגדיר מה onClick() עושה, צריך לספק קריאה חוזרת clickListener בבונה של SleepNightListener ולהקצות אותה ל-onClick().

    מתן שם ל-lambda שמטפל בקליק, clickListener , עוזר לעקוב אחריו כשהוא מועבר בין מחלקות. לפונקציית הקריאה החוזרת clickListener נדרש רק night.nightId כדי לגשת לנתונים ממסד הנתונים. הכיתה SleepNightListener המוגמרת שלכם צריכה להיראות כמו הקוד שבהמשך.
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
   fun onClick(night: SleepNight) = clickListener(night.nightId)
}
  1. פותחים את list_item_sleep_night.xml..
  2. בתוך הבלוק data, מוסיפים משתנה חדש כדי להפוך את המחלקה SleepNightListener לזמינה באמצעות קישור נתונים. נותנים ל-<variable> החדש name של clickListener. מגדירים את type לשם המלא של הכיתה com.example.android.trackmysleepquality.sleeptracker.SleepNightListener, כמו שמוצג למטה. עכשיו אפשר לגשת לפונקציה onClick() ב-SleepNightListener מהפריסה הזו.
<variable
            name="clickListener"
            type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" />
  1. כדי להאזין לקליקים על כל חלק של הפריט הזה ברשימה, מוסיפים את המאפיין android:onClick ל-ConstraintLayout.

    מגדירים את המאפיין לערך clickListener:onClick(sleep) באמצעות lambda של קשירת נתונים, כמו בדוגמה הבאה:
android:onClick="@{() -> clickListener.onClick(sleep)}"

שלב 2: מעבירים את מאזין הקליקים אל מחזיק התצוגה ואל אובייקט הקישור

  1. פותחים את SleepNightAdapter.kt.
  2. משנים את ה-constructor של המחלקה SleepNightAdapter כדי לקבל val clickListener: SleepNightListener. כשהמתאם מבצע קישור של ViewHolder, הוא צריך לספק לו את מאזין הקליקים הזה.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. ב-onBindViewHolder(), מעדכנים את הקריאה ל-holder.bind() כדי להעביר גם את מאזין הקליקים אל ViewHolder. תתקבל שגיאת קומפילציה כי הוספתם פרמטר לקריאה לפונקציה.
holder.bind(getItem(position)!!, clickListener)
  1. מוסיפים את הפרמטר clickListener ל-bind(). כדי לעשות את זה, מציבים את הסמן על השגיאה ומקישים על Alt+Enter (Windows) או על Option+Enter (Mac) על השגיאה, כמו שמוצג בצילום המסך שלמטה.

  1. בתוך המחלקה ViewHolder, בתוך הפונקציה bind(), מקצים את מאזין הקליקים לאובייקט binding. מוצגת שגיאה כי צריך לעדכן את אובייקט הקישור.
binding.clickListener = clickListener
  1. כדי לעדכן את קישור הנתונים, צריך לנקות את הפרויקט ולבנות אותו מחדש. (יכול להיות שיהיה צורך גם לבטל את התוקף של מטמונים). לכן, לקחתם מאזין קליקים מהבנאי של המתאם, והעברתם אותו עד ל-view holder ולאובייקט הקישור.

שלב 3: הצגת הודעה קצרה כשמקישים על פריט

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

  1. פותחים את SleepTrackerFragment.kt
  2. ב-onCreateView(), מחפשים את המשתנה adapter. שימו לב שמוצגת שגיאה, כי עכשיו נדרש פרמטר של מאזין לקליקים.
  3. מגדירים מאזין לקליקים על ידי העברת ביטוי למבדה אל SleepNightAdapter. פונקציית ה-lambda הפשוטה הזו מציגה הודעה קצרה עם nightId, כמו בדוגמה שלמטה. תצטרכו לייבא את Toast. בהמשך מופיעה ההגדרה המעודכנת המלאה.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})
  1. מריצים את האפליקציה, מקישים על פריטים ומוודאים שמוצגת הודעה קופצת עם הערך הנכון של nightId. מכיוון שהערכים של nightId עולים, והאפליקציה מציגה קודם את הלילה האחרון, הפריט עם הערך הכי נמוך של nightId נמצא בתחתית הרשימה.

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

שלב 1: ניווט בלחיצה

בשלב הזה, במקום להציג רק הודעה קופצת, משנים את פונקציית ה-lambda של מאזין הלחיצות ב-onCreateView() של SleepTrackerFragment כדי להעביר את nightId אל SleepTrackerViewModel ולהפעיל ניווט אל SleepDetailFragment.

מגדירים את הפונקציה לטיפול בקליקים:

  1. פותחים את SleepTrackerViewModel.kt.
  2. בתוך SleepTrackerViewModel, לקראת הסוף, מגדירים את onSleepNightClicked()פונקציית הטיפול בלחיצה.
fun onSleepNightClicked(id: Long) {

}
  1. בתוך onSleepNightClicked(), מפעילים ניווט על ידי הגדרת _navigateToSleepDetail לערך id של הלילה של השינה שנלחץ.
fun onSleepNightClicked(id: Long) {
   _navigateToSleepDetail.value = id
}
  1. הטמעה של _navigateToSleepDetail. כמו שעשיתם קודם, מגדירים private MutableLiveData למצב הניווט. וגם val ציבורי שאפשר להשיג.
private val _navigateToSleepDetail = MutableLiveData<Long>()
val navigateToSleepDetail
   get() = _navigateToSleepDetail
  1. מגדירים את השיטה לקריאה אחרי שהאפליקציה מסיימת את הניווט. קוראים לו onSleepDetailNavigated() ומגדירים את הערך שלו ל-null.
fun onSleepDetailNavigated() {
    _navigateToSleepDetail.value = null
}

מוסיפים את הקוד ל-handler של הקליקים:

  1. פותחים את SleepTrackerFragment.kt וגוללים למטה לקוד שיוצר את המתאם ומגדיר את SleepNightListener כדי להציג הודעה קופצת.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})
  1. מוסיפים את הקוד הבא מתחת להודעה הקופצת כדי להפעיל את פונקציית הטיפול בלחיצה, onSleepNighClicked(), ב-sleepTrackerViewModel כשמקישים על פריט. מעבירים את nightId כדי שמודל ה-ViewModel ידע איזו שינה להציג. במקרה כזה תופיע שגיאה, כי עדיין לא הגדרתם את onSleepNightClicked(). אתם יכולים להשאיר את ההודעה, להוסיף לה הערה או למחוק אותה, לפי הצורך.
sleepTrackerViewModel.onSleepNightClicked(nightId)

מוסיפים את הקוד כדי לעקוב אחרי קליקים:

  1. פותחים את SleepTrackerFragment.kt.
  2. ב-onCreateView(), ממש מעל ההצהרה של manager, מוסיפים קוד כדי לעקוב אחרי navigateToSleepDetail LiveData החדש. כשערך navigateToSleepDetail משתנה, עוברים אל SleepDetailFragment, מעבירים את night ואז קוראים ל-onSleepDetailNavigated(). מכיוון שכבר עשית את זה בעבר ב-codelab קודם, הנה הקוד:
sleepTrackerViewModel.navigateToSleepDetail.observe(this, Observer { night ->
            night?.let {
              this.findNavController().navigate(
                        SleepTrackerFragmentDirections
                                .actionSleepTrackerFragmentToSleepDetailFragment(night))
               sleepTrackerViewModel.onSleepDetailNavigated()
            }
        })
  1. מריצים את הקוד, לוחצים על פריט כלשהו, והאפליקציה קורסת.

טיפול בערכי null במתאמי הקישור:

  1. מריצים את האפליקציה שוב במצב ניפוי באגים. מקישים על פריט ומסננים את היומנים כדי להציג שגיאות. יוצג מעקב אחר מחסנית, כולל משהו שדומה למה שמופיע בהמשך.
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter item

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

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

  1. ב-BindingUtils.kt, לכל אחד מהמתאמים של הקישור, משנים את הסוג של הארגומנט item ל-nullable, ועוטפים את הגוף ב-item?.let{...}. לדוגמה, המתאם שלכם ל-sleepQualityString ייראה כך. משנים את שאר המתאמים באופן דומה.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight?) {
   item?.let {
       text = convertNumericQualityToString(item.sleepQuality, context.resources)
   }
}
  1. מריצים את האפליקציה, מקישים על פריט ונפתחת תצוגת פרטים.

פרויקט Android Studio: ‏ RecyclerViewClickHandler.

כדי שפריטים ב-RecyclerView יגיבו לקליקים, צריך לצרף click listeners לפריטים ברשימה ב-ViewHolder ולטפל בקליקים ב-ViewModel.

כדי שפריטים ב-RecyclerView יגיבו לקליקים, צריך לבצע את הפעולות הבאות:

  • יוצרים מחלקה של מאזין שמקבלת lambda ומקצה אותה לפונקציה onClick().
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
   fun onClick(night: SleepNight) = clickListener(night.nightId)
}
  • מגדירים את מאזין הקליקים בתצוגה.
android:onClick="@{() -> clickListener.onClick(sleep)}"
  • מעבירים את מאזין הקליקים לבונה המתאם, ל-ViewHolder ומוסיפים אותו לאובייקט הקישור.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()
holder.bind(getItem(position)!!, clickListener)
binding.clickListener = clickListener
  • בקטע שבו מוצגת תצוגת ה-recycler, שבו יוצרים את המתאם, מגדירים מאזין לקליקים על ידי העברת lambda למתאם.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
      sleepTrackerViewModel.onSleepNightClicked(nightId)
})
  • מטמיעים את handler הקליקים במודל התצוגה. בדרך כלל, קליקים על פריטים ברשימה מפעילים ניווט אל קטע פרטים.

קורס ב-Udacity:

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

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

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

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

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

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

שאלה 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.

לשיעור הבא: 7.5: כותרות ב-RecyclerView