בדרך כלל עדיף לייצג תהליכי כניסה, אשפים או תהליכי משנה אחרים באפליקציה בתור תרשים ניווט בתצוגת עץ. כשאתם ממקמים בתוך תפריטי הניווט המשניים תפריטי משנה עצמאיים, קל יותר להבין ולנהל את התהליך הראשי של ממשק המשתמש של האפליקציה.
בנוסף, אפשר לעשות שימוש חוזר בגרפים בתצוגת עץ. הם גם מספקים רמה מסוימת של אנקפסולציה – ליעדים מחוץ לתרשים המורכב אין גישה ישירה לאף אחד מהיעדים בתרשים המורכב. במקום זאת, צריך להגדיר את navigate()
לתרשים ההשתייכות עצמו, שבו הלוגיקה הפנימית יכולה להשתנות בלי להשפיע על שאר התרשים.
דוגמה
תרשים הניווט ברמה העליונה של האפליקציה צריך להתחיל ביעד הראשוני שהמשתמש רואה כשמפעילים את האפליקציה, ולכלול את היעדים שהוא רואה כשנע בתוך האפליקציה.
לדוגמה, נניח שרוצים לחייב את המשתמש לראות את המסכים title_screen ו-register רק כשהאפליקציה מופעלת בפעם הראשונה. לאחר מכן, פרטי המשתמש מאוחסנים, ובפעמים הבאות שהמשתמשים יפעילו את האפליקציה, הם יועברו ישירות למסך התאמה.
מומלץ להגדיר את המסך match בתור יעד ההתחלה של תרשים הניווט ברמה העליונה, ולהעביר את המסכים title ו-register לתרשים בתצוגת עץ, כפי שמוצג באיור 1:
כשמסך ההתאמה יוצג, בודקים אם יש משתמש רשום. אם המשתמש לא רשום, מפנים אותו למסך הרישום.
מידע נוסף על תרחישים של ניווט מותנה זמין במאמר ניווט מותנה.
פיתוח נייטיב
כדי ליצור תרשים ניווט בתצוגת עץ באמצעות Compose, משתמשים בפונקציה NavGraphBuilder.navigation()
. משתמשים בפונקציה navigation()
בדיוק כמו בפונקציות NavGraphBuilder.composable()
ו-NavGraphBuilder.dialog()
כשמוסיפים יעדים לגרף.
ההבדל העיקרי הוא ש-navigation
יוצר תרשים בתצוגת עץ במקום יעד חדש. לאחר מכן, קוראים לפונקציות composable()
ו-dialog()
בתוך הפונקציה הלוגריתמית של navigation()
כדי להוסיף יעדים לתרשים המורכב.
קטע הקוד הבא ממחיש איך מטמיעים את התרשים שמוצג באיור 2 באמצעות Compose:
// Routes
@Serializable object Title
@Serializable object Register
// Route for nested graph
@Serializable object Game
// Routes inside nested graph
@Serializable object Match
@Serializable object InGame
@Serializable object ResultsWinner
@Serializable object GameOver
NavHost(navController, startDestination = Title) {
composable<Title> {
TitleScreen(
onPlayClicked = { navController.navigate(route = Register) },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<Register> {
RegisterScreen(
onSignUpComplete = { navController.navigate(route = Game) }
)
}
navigation<Game>(startDestination = Match) {
composable<Match> {
MatchScreen(
onStartGame = { navController.navigate(route = InGame) }
)
}
composable<InGame> {
InGameScreen(
onGameWin = { navController.navigate(route = ResultsWinner) },
onGameLose = { navController.navigate(route = GameOver) }
)
}
composable<ResultsWinner> {
ResultsWinnerScreen(
onNextMatchClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
},
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<GameOver> {
GameOverScreen(
onTryAgainClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
}
)
}
}
}
כדי לעבור ישירות ליעד בתצוגת עץ, משתמשים בסוג מסלול כמו בכל יעד אחר. הסיבה לכך היא שמסלולים הם מושג גלובלי שמשמש לזיהוי יעדים שאפשר לנווט אליהם מכל מסך:
navController.navigate(route = Match)
XML
כשמשתמשים ב-XML, אפשר להשתמש בכלי הניווט כדי ליצור את התרשים המורכב. כדי לעשות זאת:
- בעורך הניווט, לוחצים לחיצה ארוכה על מקש Shift ולוחצים על היעדים שרוצים לכלול בתרשים ההיררכי.
לוחצים לחיצה ימנית כדי לפתוח את תפריט ההקשר, ובוחרים באפשרות Move to Nested Graph (העברה לתרשים בתצוגת עץ) > New Graph (תרשים חדש). היעדים מוקפים בתרשים בתצוגת עץ. באיור 2 מוצג תרשים בתצוגת עץ בכלי הניווט:
לוחצים על התרשים המורכב. המאפיינים הבאים מופיעים בחלונית מאפיינים:
- Type (סוג), שמכיל את האפשרות 'Nested Graph' (תרשים בתצוגת עץ)
- ID, שמכיל מזהה שהמערכת הקצה לתרשים ההשתייכות. המזהה הזה משמש להפניה לתרשים המורכב מהקוד שלכם.
לוחצים לחיצה כפולה על התרשים המורכב כדי להציג את היעדים שלו.
לוחצים על הכרטיסייה טקסט כדי לעבור לתצוגת ה-XML. נוסף לתרשים גרף ניווט בתצוגת עץ. לתרשים הניווט הזה יש רכיבי
navigation
משלו, מזהה משלו ומאפייןstartDestination
שמצביע על היעד הראשון בתרשים ההשתייכות:<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.cashdog.cashdog.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_mainFragment_to_sendMoneyGraph" app:destination="@id/sendMoneyGraph" /> <action android:id="@+id/action_mainFragment_to_viewBalanceFragment" app:destination="@id/viewBalanceFragment" /> </fragment> <fragment android:id="@+id/viewBalanceFragment" android:name="com.example.cashdog.cashdog.ViewBalanceFragment" android:label="fragment_view_balance" tools:layout="@layout/fragment_view_balance" /> <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient"> <fragment android:id="@+id/chooseRecipient" android:name="com.example.cashdog.cashdog.ChooseRecipient" android:label="fragment_choose_recipient" tools:layout="@layout/fragment_choose_recipient"> <action android:id="@+id/action_chooseRecipient_to_chooseAmountFragment" app:destination="@id/chooseAmountFragment" /> </fragment> <fragment android:id="@+id/chooseAmountFragment" android:name="com.example.cashdog.cashdog.ChooseAmountFragment" android:label="fragment_choose_amount" tools:layout="@layout/fragment_choose_amount" /> </navigation> </navigation>
בקוד, מעבירים את מזהה המשאב של הפעולה שמחברת את תרשים השורש לתרשים ההשתייכות:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- חוזרים לכרטיסייה Design ולוחצים על Root כדי לחזור לתרשים הבסיס.
הפניה לגרפים אחרים של ניווט באמצעות include
דרך נוספת ליצור מודולים במבנה של תרשים היא לכלול תרשים אחד בתוך תרשים אחר באמצעות רכיב <include>
בתרשים הניווט של ההורה. כך אפשר להגדיר את התרשים הכלול במודול נפרד או בפרויקט נפרד לגמרי, וכך להגדיל את האפשרות לשימוש חוזר.
קטע הקוד הבא מראה איך משתמשים ב-<include>
:
<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/fragment">
<strong><include app:graph="@navigation/included_graph" /></strong>
<fragment
android:id="@+id/fragment"
android:name="com.example.myapplication.BlankFragment"
android:label="Fragment in Root Graph"
tools:layout="@layout/fragment_blank">
<strong><action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" /></strong>
</fragment>
...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<strong>android:id="@+id/second_graph"</strong>
app:startDestination="@id/includedStart">
<fragment
android:id="@+id/includedStart"
android:name="com.example.myapplication.IncludedStart"
android:label="fragment_included_start"
tools:layout="@layout/fragment_included_start" />
</navigation>
מקורות מידע נוספים
מידע נוסף על ניווט זמין במקורות המידע הבאים.