שמירה וניהול של מצב הניווט

בקטעים הבאים מתוארות אסטרטגיות לשמירת סטאק החזרה אחורה ולשמירה של המצב המשויך לרשומים בסטאק החזרה אחורה.

שמירת סטאק הקוד הקודם

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

שימוש ב-rememberNavBackStack

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

כדי ש-rememberNavBackStack יפעל כראוי, כל מפתח ב-back stack צריך לעמוד בדרישות ספציפיות:

  • הטמעת הממשק NavKey: כל מפתח ב-back stack צריך להטמיע את הממשק NavKey. הוא משמש כממשק של סמן שמאותת לספרייה שאפשר לשמור את המפתח.
  • הערה @Serializable: בנוסף להטמעת NavKey, צריך לסמן את הכיתות והאובייקטים של המפתחות באמצעות ההערה @Serializable.

בקטע הקוד הבא מוצגת הטמעה נכונה של rememberNavBackStack:

@Serializable
data object Home : NavKey

@Composable
fun NavBackStack() {
    val backStack = rememberNavBackStack(Home)
}

חלופה: אחסון ב-ViewModel

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

  • מוודאים שהמפתחות ניתנים לסריאליזציה: בדומה למפתח rememberNavBackStack, מפתחות הניווט צריכים להיות ניתנים לסריאליזציה.
  • טיפול בסריאליזציה ובפענוח (deserialization) באופן ידני: אתם אחראים לשמור באופן ידני את הייצוג המסודר של כל מפתח באחסון מתמיד (למשל, SharedPreferences, מסד נתונים או קובץ) כשהאפליקציה עוברת לרקע או כשהיא משוחזרת.

הגדרת היקף של ViewModels ל-NavEntrys

ViewModels משמשים לשמירת המצב שקשור לממשק המשתמש במהלך שינויים בתצורה, כמו סיבוב המסך. כברירת מחדל, הערכים של ViewModels מוגדרים ברמת ViewModelStoreOwner הקרוב ביותר, שבדרך כלל הוא Activity או Fragment.

עם זאת, יכול להיות שתרצו להגביל את ההיקף של ViewModel ל-NavEntry ספציפי (כלומר, מסך או יעד ספציפיים) בסטאק האחורי, במקום ל-Activity כולו. כך מובטח שהמצב של ViewModel נשמר רק כל עוד ה-NavEntry הספציפי הזה נמצא ב-back stack, ונמחק כשה-NavEntry מוסר מה-stack.

ספריית התוספים androidx.lifecycle:lifecycle-viewmodel-navigation3 מספקת NavEntryDecorator שמאפשר לעשות זאת. ה-decorator הזה מספק ViewModelStoreOwner לכל NavEntry. כשיוצרים ViewModel בתוך תוכן של NavEntry (למשל, באמצעות viewModel() ב-Compose), ההיקף שלו מוגדר באופן אוטומטי למפתח הספציפי של NavEntry ב-back stack. כלומר, הערך של ViewModel נוצר כשהערך של NavEntry מתווסף ל-back stack, ונמחק כשהערך של NavEntry מוסר.

כדי להשתמש ב-NavEntryDecorator כדי להגדיר את ההיקף של ViewModel ל-NavEntry, מבצעים את השלבים הבאים:

  1. מוסיפים את יחסי התלות של androidx.lifecycle:lifecycle-viewmodel-navigation3 לקובץ app/build.gradle.kts.
  2. מוסיפים את rememberSavedStateNavEntryDecorator() לרשימת entryDecorators כשמגדירים NavDisplay.
  3. מוסיפים עוד מאיירים ל-NavDisplay.

NavDisplay(
    entryDecorators = listOf(
        // Add the default decorators for managing scenes and saving state
        rememberSceneSetupNavEntryDecorator(),
        rememberSavedStateNavEntryDecorator(),
        // Then add the view model store decorator
        rememberViewModelStoreNavEntryDecorator()
    ),
    backStack = backStack,
    entryProvider = entryProvider { },
)