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

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

שמירת ערימת החזרה

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

שימוש ב-rememberNavBackStack

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

כדי שהלחצן rememberNavBackStack יפעל בצורה תקינה, כל מקש במחסנית החזרה צריך לעמוד בדרישות ספציפיות:

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

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

@Serializable
data object Home : NavKey

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

אפשרות חלופית: אחסון ב-ViewModel

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

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

הגדרת היקף של ViewModel שניות ל-NavEntry שניות

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

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

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

כדי להשתמש ב-NavEntryDecorator להגדרת היקף ViewModels ל-NavEntrys, פועלים לפי השלבים הבאים:

  1. מוסיפים את התלות androidx.lifecycle:lifecycle-viewmodel-navigation3 לקובץ app/build.gradle.kts.
  2. מוסיפים את rememberSaveableStateHolderNavEntryDecorator() לרשימה של 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 { },
)