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

יצירת סטאק אחורה
בתרחיש ניווט 3, סטאק החזרה לא מכיל תוכן בפועל. במקום זאת, הוא מכיל אזכורים לתוכן, שנקראים מפתחות. המפתחות יכולים להיות מכל סוג, אבל בדרך כלל הם כיתות נתונים פשוטות שניתן לסדר בסדרה. היתרונות של שימוש בהפניות במקום בתוכן:
- קל לנווט בלחיצה על מקשים בסטאק העורפי.
- כל עוד המפתחות ניתנים לסריאליזציה, אפשר לשמור את סטאק החזרה אחורה באחסון מתמיד, כך שהוא ישרוד שינויים בהגדרות וסיום תהליך. זה חשוב כי המשתמשים מצפים לצאת מהאפליקציה, לחזור אליה מאוחר יותר ולהמשיך מהמקום שבו הם הפסיקו, עם אותו תוכן שמוצג. מידע נוסף זמין במאמר שמירה של סטאק הקודם.
מושג מפתח ב-Navigation 3 API הוא שהסטאק של החזרה לאחור הוא בבעלותכם. הספרייה:
- המערכת מצפה שהסטאק האחורי יהיה
List<T>
מגובה בתמונת מצב, כאשרT
הוא הסוג של הסטאק האחוריkeys
. אפשר להשתמש ב-Any
או לספק מפתחות משלכם עם סוג חזק יותר. כשאתם רואים את המונחים 'push' או 'pop', ההטמעה הבסיסית היא הוספה או הסרה של פריטים בסוף רשימה. - הוא עוקב אחרי סטאק הקודם ומשקף את המצב שלו בממשק המשתמש באמצעות
NavDisplay
.
בדוגמה הבאה מוסבר איך ליצור מפתחות וסטאק חזרה, ולשנות את סטאק החזרה בתגובה לאירועי ניווט של משתמשים:
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
איך פותרים מפתחות לתוכן
תוכן ב-Navigation 3 מתואר באמצעות NavEntry
, שהיא כיתה שמכילה פונקציה שניתנת ליצירה. הוא מייצג יעד – קטע תוכן יחיד שהמשתמש יכול לנווט קדימה אליו וחזרה ממנו.
ה-NavEntry
יכול להכיל גם מטא-נתונים – מידע על התוכן. אובייקטים של מאגרים, כמו NavDisplay
, יכולים לקרוא את המטא-נתונים האלה כדי להחליט איך להציג את התוכן של NavEntry
. לדוגמה, אפשר להשתמש במטא-נתונים כדי לשנות את אנימציות ברירת המחדל של NavEntry
ספציפי. NavEntry metadata
היא מפה של מפתחות String
לערכים Any
, שמספקת אחסון נתונים גמיש.
כדי להמיר key
ל-NavEntry
, יוצרים ספק רשומות. זוהי פונקציה שמקבלת key
ומחזירה NavEntry
עבור key
הזה. בדרך כלל הוא מוגדר כפרמטר lambda כשיוצרים NavDisplay
.
יש שתי דרכים ליצור ספק של רשומות: ליצור פונקציית lambda ישירות או להשתמש ב-DSL של entryProvider
.
יצירת פונקציית ספק רשומות ישירות
בדרך כלל יוצרים פונקציית Entry Provider באמצעות משפט when
, עם הסתעפות לכל אחד מהמפתחות.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
שימוש ב-entryProvider
DSL
באמצעות ה-DSL של entryProvider
תוכלו לפשט את פונקציית הלמהדה, כי לא תצטרכו לבדוק את כל סוגי המפתחות ולבנות NavEntry
לכל אחד מהם.
לשם כך, משתמשים בפונקציית ה-builder entryProvider
. הוא כולל גם התנהגות ברירת מחדל לחלופין (הצגת שגיאה) אם המפתח לא נמצא.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
שימו לב לפרטים הבאים בקטע הקוד:
entry
משמש להגדרתNavEntry
עם הסוג והתוכן הניתנים ליצירהentry
מקבל פרמטרmetadata
כדי להגדיר אתNavEntry.metadata
הצגת מחסנית הקודמים
סטאק החזרה לאחור מייצג את מצב הניווט באפליקציה. בכל פעם שסטאק החזרה אחורה משתנה, ממשק המשתמש של האפליקציה צריך לשקף את המצב החדש של סטאק החזרה אחורה. ב-Navigation 3, NavDisplay
עוקב אחרי סטאק החזרה ומעדכן את ממשק המשתמש בהתאם. יוצרים אותו עם הפרמטרים הבאים:
- סטאק החזרה – הוא צריך להיות מסוג
SnapshotStateList<T>
, כאשרT
הוא הסוג של מפתחות סטאק החזרה. הואList
שניתן לצפות בו, כך שהוא מפעיל יצירת קומפוזיציה מחדש שלNavDisplay
כשהוא משתנה. entryProvider
להמרת המפתחות ב-back stack ל-NavEntry
.- אפשר גם לספק פונקציית lambda לפרמטר
onBack
. הקריאה הזו מתבצעת כשהמשתמש מפעיל אירוע חזרה אחורה.
הדוגמה הבאה מראה איך יוצרים NavDisplay
.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
כברירת מחדל, ב-NavDisplay
מוצג ה-NavEntry
העליון ביותר בסטאק האחורי, בפריסה של חלונית אחת. בהקלטה הבאה מוצגת האפליקציה הזו פועלת:

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

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