החלת לוגיקה או עטיפות על יעדים

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

יצירת דקורטור בהתאמה אישית

כדי ליצור דקורטור, מרחיבים את המחלקה NavEntryDecorator ומבטלים את השיטות הבאות:

  • decorate – פונקציית למבדה קומפוזבילית שמופעלת עבור כל NavEntry במחסנית החזרה. היא מקבלת את NavEntry כפרמטר. כך אפשר ליצור אובייקטים של מצב שמקבלים את המפתח שלהם מהמאפיין contentKey של הרשומה. אפשר להשתמש ב-CompositionLocalProvider כדי לספק תלויות בתוכן של הרשומה. אפשר גם להקיף את התוכן בפונקציה שאפשר להרכיב, או להפעיל תופעות לוואי. תמיד צריך להפעיל את entry.Content() בתוך השיטה הזו.
  • onPop – קריאה חוזרת שמופעלת כש-NavEntry הוסר ממחסנית החזרה ויצא מהקומפוזיציה. הוא מקבל את contentKey של הרשומה שהוסרה. משתמשים ב-contentKey כדי לזהות ולנקות את כל המצב שמשויך לרשומה הזו.

בדוגמה הבאה מורחבת המחלקה NavEntryDecorator כדי ליצור דקורטור בהתאמה אישית.

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

אם הדקורטור צריך גישה למצב, יוצרים פונקציה שניתנת להגדרה שיוצרת את המצב הזה, ואז משתמשים בה כדי ליצור את הדקורטור. דוגמה להטמעה מופיעה בקוד המקור של rememberSaveableStateHolderNavEntryDecorator. הפעולה הזו יוצרת את המצב – SaveableStateHolder – ומשתמשת בו כדי ליצור את ה-decorator.

עיצוב מקבץ פעילויות קודמות

אחרי שיוצרים את NavEntryDecorator, אפשר להוסיף קישוטים לרשומות במחסנית האחורית באחת משתי דרכים:

  • שימוש ב-rememberDecoratedNavEntries. הפונקציה הזו שימושית כשמשתמשים בכמה מחסניות חזרה, שלכל אחת מהן יש קבוצה משלה של מעצבים (פרטים נוספים זמינים במתכון הקוד הזה). הפונקציה מחזירה רשימה מעוטרת של NavEntry שאפשר להשתמש בה עם NavDisplay.
  • מעבירים את ה-decorator ישירות אל NavDisplay באמצעות הפרמטר entryDecorators. ‫NavDisplay calls rememberDecoratedNavEntries מתחת לפני השטח ומציג את הרשומות המעוצבות.

הכללת מעצב ברירת המחדל

‫Navigation 3 כולל מעצב ברירת מחדל בשם SaveableStateHolderNavEntryDecorator שמאפשר לשמור את המצב של NavEntry גם אחרי שינויים בהגדרות וגם אחרי שהתהליך מסתיים. הוא עוטף את התוכן של NavEntry ב-SaveableStateProvider, וכך מאפשר לקריאות של rememberSaveable בתוך התוכן של NavEntry לפעול בצורה תקינה.

אלא אם ה-Decorator מספק SaveableStateProvider, צריך לכלול את SaveableStateHolderNavEntryDecorator כ-Decorator הראשון ברשימת ה-Decorators שסופקו. הוא נוצר באמצעות rememberSaveableStateHolderNavEntryDecorator.

לדוגמה:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

מתי כדאי להשתמש ב-decorator

אפשר להשתמש ב-decorator כדי:

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

אין להשתמש ב-decorator כדי:

  • העברת תלות ל-NavEntry יחיד.
  • מספקים יחסי תלות שההיקף שלהם רחב יותר מזה של ערימת הפעולות הקודמות.

בשני המקרים האלה, צריך להעביר את התלות ישירות כשיוצרים את NavEntry במקום זאת.

דוגמאות קוד נוספות זמינות במאמר NavEntryDecorator.