השדה NavController
מכיל 'מקבץ גיבוי' שמכיל את היעדים של המשתמשים
ביקרת במקום. כשהמשתמש מנווט למסכים באפליקציה שלכם,
NavController
מוסיפה ומסירה יעדים למקבץ האחורי או ממנו.
בתור מקבץ, המקבץ האחורי הוא "האחרון נכנס", של מבנה הנתונים.
לכן, NavController
מעביר פריטים אל החלק העליון של המסך ומקפיץ אותם
סטאק.
התנהגות בסיסית
אלה העובדות העיקריות שצריך לקחת בחשבון לגבי התנהגות הגב מקבץ:
- יעד ראשון: כשהמשתמש פותח את האפליקציה, השדה
NavController
דוחפת את היעד הראשון לחלק העליון של המקבץ האחורי. - העברה למקבץ: כל שיחה
NavController.navigate()
דוחפת את היעד הנתון לראש הערימה. - יעד מוביל שקופץ: הקשה על למעלה או על חזרה מפעילה את
NavController.navigateUp()
וגםNavController.popBackStack()
שיטות, בהתאמה. הם מקפיצים את היעד העליון מהמקבץ. לצפייה מידע נוסף על ההבדלים בדף עקרונות הניווט בין Up לבין Back.
חזרה לחלון הראשי
השיטה NavController.popBackStack()
מנסה להקפיץ את הקובץ הנוכחי
את היעד מהמקבץ האחורי ומנווטים ליעד הקודם. הזה
מחזיר את המשתמש בצורה יעילה שלב אחד אחורה בהיסטוריית הניווט. הוא מחזיר
ערך בוליאני שמציין אם הוא חזר בהצלחה ליעד.
חזרה ליעד ספציפי
אפשר גם להשתמש בpopBackStack()
כדי לנווט ליעד מסוים. לבצע
אז השתמשו באחד מעומסי-היתר שלו. יש כמה מודלים שמאפשרים לך להעביר
למשל, מספר שלם id
או מחרוזת route
. עומסי היתר האלה
של המשתמש ליעד שמשויך למזהה הנתון. ביקורתית,
הם קופצים כל מה שמופיע על הערימה מעל היעד הזה.
גם עומסי היתר האלה מקבלים ערך בוליאני של inclusive
. הוא קובע אם
NavController
צריך גם להקפיץ את היעד שצוין מהמקבץ האחורי
אחרי שמנווטים אליו.
כדוגמה, נבחן את קטע הקוד הקצר הבא:
navController.popBackStack(R.id.destinationId, true)
כאן הערך של NavController
מחזיר את היעד ליעד עם המזהה השלם
destinationId
. מכיוון שהערך של הארגומנט inclusive
הוא true
,
NavController
גם יקפיץ את היעד הנתון מהמקבץ האחורי.
טיפול בחלון קופץ שנכשל
כשה-popBackStack()
יחזיר את הערך false
, תתבצע קריאה נוספת אל
הפונקציה NavController.getCurrentDestination()
מחזירה null
. המשמעות היא שיש לאפליקציה
הקפיץ את היעד האחרון מהמקבץ. במקרה כזה, המשתמש יראה רק
מסך ריק.
מצב כזה יכול להתרחש במקרים הבאים:
- הערימה של
popBackStack()
לא הופצה. - הערימה הועברה על ידי
popBackStack()
ריקה.
כדי לפתור את הבעיה, צריך לנווט ליעד חדש או להתקשר למספר finish()
על הפעילות שלך כדי לסיים אותה. קטע הקוד הבא מדגים את זה:
קוטלין
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
Java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
חלון קופץ עבור יעד
כדי להסיר יעדים מהמקבץ האחורי כשמנווטים מיעד אחד
בפונקציה אחרת, צריך להוסיף ארגומנט popUpTo()
לפונקציה navigate()
המשויכת
שיחה. popUpTo()
מורה לספריית הניווט להסיר יעדים מסוימים
מהמקבץ האחורי כחלק מהשיחה אל navigate()
. ערך הפרמטר הוא
המזהה של יעד במקבץ האחורי. המזהה יכול להיות
מספר שלם id
או מחרוזת route
.
אפשר לכלול ארגומנט לפרמטר inclusive
עם הערך true
כדי לציין שהיעד שציינת ב-popUpTo()
צריך גם
חלון קופץ עם מקבץ אחורי.
כדי ליישם את זה באופן פרוגרמטי, צריך להעביר את popUpTo()
אל navigate()
כחלק מ
NavOptions
עם inclusive
מוגדר ל-true
. אפשר לעשות את זה גם בקטע 'כתיבה' וגם
צפיות.
שמירת המצב בחלון קופץ
כשמשתמשים ב-popUpTo
כדי לנווט ליעד, אפשר לשמור את
מקבץ גיבויים (backStack) והמצבים של כל היעדים שהופצו מהמקבץ האחורי. אפשר
ואז לשחזר את המקבץ לאחור ואת היעדים כשמנווטים ליעד הזה
במועד מאוחר יותר. כך אפשר לשמור מצב של יעד נתון
כמה אשכולות חזרה.
כדי לעשות זאת באופן פרוגרמטי, צריך לציין את הערך saveState = true
כשמוסיפים את popUpTo
אל
באפשרויות הניווט שלכם.
אפשר גם לציין restoreState = true
באפשרויות הניווט כדי
ישחזר באופן אוטומטי את המקבץ האחורי ואת המצב שמשויך
היעד.
לדוגמה:
navController.navigate(
route = route,
navOptions = navOptions {
popUpTo<A>{ saveState = true }
restoreState = true
}
)
כדי להפעיל שמירה ושחזור של מצב ב-XML, צריך להגדיר את popUpToSaveState
בתור true
ו-restoreState
בתור true
בהתאמה ב-action
המשויך.
דוגמה בפורמט XML
הנה דוגמה של popUpTo
ב-XML, באמצעות פעולה:
<action
android:id="@+id/action_a_to_b"
app:destination="@id/b"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"
app:restoreState=”true”
app:popUpToSaveState="true"/>
כתיבת דוגמה
הנה דוגמה מלאה לכך בכלי 'כתיבה':
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: Any = A
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable<A> {
DestinationA(
onNavigateToB = {
// Pop everything up to, and including, the A destination off
// the back stack, saving the back stack and the state of its
// destinations.
// Then restore any previous back stack state associated with
// the B destination.
// Finally navigate to the B destination.
navController.navigate(route = B) {
popUpTo<A> {
inclusive = true
saveState = true
}
restoreState = true
}
},
)
}
composable<B> { DestinationB(/* ... */) }
}
}
@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
Button(onClick = onNavigateToB) {
Text("Go to A")
}
}
באופן מפורט יותר, אפשר לשנות את האופן שבו מתקשרים ל-NavController.navigate()
בדרכים הבאות:
// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a")
}
// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a") { inclusive = true }
}
// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
launchSingleTop = true
}
למידע כללי על העברת אפשרויות אל NavController.navigate()
, אפשר לעיין במאמר
המדריך לניווט עם אפשרויות.
הבלטה באמצעות פעולות
כשמנווטים באמצעות פעולה, אפשר לבחור יעדים נוספים להקפצת מהמקבץ האחורי. לדוגמה, אם לאפליקציה שלכם יש תהליך התחברות ראשוני, פעם אחת משתמש התחבר, עליך להשבית את כל היעדים הקשורים להתחברות של המקבץ 'הקודם', כך שלחצן 'הקודם' לא יחזיר את המשתמשים להתחברות .
מקורות מידע נוספים
מידע נוסף זמין בדפים הבאים:
- ניווט מעגלי: איך להימנע מעומס יתר לבצע סטאק במקרים שבהם תהליכי הניווט הם מעגליים.
- יעדי תיבות דו-שיח: מידע על האופן שבו יעדים של תיבת דו-שיח מוצגים שיקולים ייחודיים לניהול המקבץ.