רכיב הניווט מספק דרך פשוטה וכללית לנווט ליעד. הממשק הזה תומך במגוון הקשרים ובמסגרות של ממשקי משתמש. לדוגמה, אפשר להשתמש ברכיב הניווט עם Compose, תצוגות, מקטעים, פעילויות ואפילו מסגרות UI מותאמות אישית.
במדריך הזה מוסבר איך להשתמש ברכיב Navigation כדי לנווט ליעד בהקשרים שונים.
שימוש ב-NavController
סוג המפתח שמשמש למעבר בין יעדים הוא NavController.
מידע נוסף על המחלקה עצמה ועל אופן יצירת מופע שלה זמין במאמר יצירת בקר ניווט. במדריך הזה מוסבר איך להשתמש בו.
ניווט
לא משנה באיזו מסגרת של ממשק משתמש משתמשים, יש פונקציה אחת שאפשר להשתמש בה כדי לנווט ליעד: NavController.navigate().
יש הרבה עומסים עודפים שזמינים ל-navigate(). ההצפה שצריך לבחור תלויה בהקשר המדויק. לדוגמה, צריך להשתמש בעומס יתר אחד כשעוברים לרכיב שאפשר להרכיב ממנו ממשק משתמש, ועומס יתר אחר כשעוברים לתצוגה.
בקטעים הבאים מפורטים כמה מהעומסים העיקריים של navigate() שבהם אפשר להשתמש.
מעבר לרכיב קומפוזבילי
כדי לנווט אל קומפוזבילי, צריך להשתמש ב-NavController.navigate<T>.
במקרה של עומס יתר כזה, הפונקציה navigate() מקבלת ארגומנט יחיד route שמעבירים לו סוג. הוא משמש כמפתח ליעד.
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
כדי לנווט לרכיב שאפשר להרכיב בתרשים הניווט, קודם צריך להגדיר את NavGraph כך שכל יעד יתאים לסוג. לפונקציות composable, משתמשים בפונקציה composable().
חשיפת אירועים מרכיבי ה-Composable
כשפונקציה ניתנת להגדרה וצריך לנווט ממנה למסך חדש, לא כדאי להעביר לה הפניה אל NavController כדי שהיא תוכל לקרוא ל-navigate() ישירות.
בהתאם לעקרונות של זרימת נתונים חד-כיוונית (UDF), במקום זאת, רכיב ה-composable צריך לחשוף אירוע שרכיב ה-NavController מטפל בו.
במילים אחרות, לרכיב הניתן להרכבה צריך להיות פרמטר מסוג () -> Unit.
כשמוסיפים יעדים ל-NavHost באמצעות הפונקציה composable(), מעבירים את הפונקציה הניתנת להגדרה לקריאה אל NavController.navigate().
דוגמה לכך מופיעה בסעיף המשנה הבא.
.דוגמה
כדי להמחיש את מה שמוסבר בקטעים הקודמים, אפשר לראות את הנקודות האלה בקטע הקוד הבא:
- כל יעד בתרשים נוצר באמצעות נתיב, שהוא אובייקט או מחלקה שניתנים לסריאליזציה ומתארים את הנתונים שנדרשים ליעד הזה.
- הרכיב הקומפוזבילי
MyAppNavHostמכיל את המופע שלNavController. - לכן, קריאות ל-
navigate()צריכות להתבצע שם ולא ברכיב נמוך יותר כמוProfileScreen. -
ProfileScreenמכיל לחצן שמוביל את המשתמש אלFriendsListכשהוא לוחץ עליו. עם זאת, היא לא קוראת ל-navigate()בעצמה. - במקום זאת, הכפתור קורא לפונקציה שמוצגת כפרמטר
onNavigateToFriends. - כש-
MyAppNavHostמוסיף אתProfileScreenלתרשים הניווט, הוא מעביר ל-onNavigateToFriendsפונקציית למדה שקוראת ל-navigate(route = FriendsList). - כך מוודאים שכשהמשתמש לוחץ על הכפתור
ProfileScreen, הוא מועבר בצורה נכונה אלFriendsListScreen.
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
ניווט באמצעות מזהה מספר שלם
כדי לעבור ליעד באמצעות מזהה מספר שלם, קוראים ל-navigate(int)
overload. הוא מקבל את מזהה המשאב של פעולה או של יעד. בקטע הקוד הבא אפשר לראות איך משתמשים בעומס יתר הזה כדי לעבור אל ViewTransactionsFragment:
Kotlin
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Java
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
כשמנווטים באמצעות מזהים, מומלץ להשתמש בפעולות כשהדבר אפשרי. הפעולות מספקות מידע נוסף בתרשים הניווט, ומציגות באופן ויזואלי את הקשר בין היעדים.
ניווט באמצעות NavDeepLinkRequest
כדי לעבור אל יעד של קישור עומק מרומז, משתמשים בעומס היתר של navigate(NavDeepLinkRequest). בקטע הקוד הבא מוצגת הטמעה של השיטה הזו:
Kotlin
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Java
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
בניגוד לניווט באמצעות מזהי פעולה או יעד, אתם יכולים לנווט לכל קישור עמוק בתרשים, בלי קשר לשאלה אם היעד גלוי. אפשר לנווט ליעד בגרף הנוכחי או ליעד בגרף אחר לגמרי.
פעולות וסוגי MIME
בנוסף ל-Uri, NavDeepLinkRequest תומך גם בקישורי עומק עם פעולות וסוגי MIME. כדי להוסיף פעולה לבקשה, משתמשים ב-fromAction() או ב-setAction(). כדי להוסיף סוג MIME לבקשה, משתמשים ב-fromMimeType() או ב-setMimeType().
כדי ש-NavDeepLinkRequest יתאים ליעד של קישור עומק מרומז, ה-URI, הפעולה וסוג ה-MIME צריכים להיות זהים ל-NavDeepLink ביעד. מזהי ה-URI צריכים להתאים לתבנית, הפעולות צריכות להיות זהות וסוגי ה-MIME צריכים להיות קשורים. לדוגמה, image/jpg תואם ל-image/\*
הקשרים נוספים
במאמר הזה מוסבר איך להשתמש ב-NavController.navigate() בתרחישי השימוש הנפוצים ביותר. עם זאת, לפונקציה יש טווח של עומסים יתרים שאפשר להשתמש בהם בהקשרים שונים, ובמקביל לכל מסגרת Ui. פרטים נוספים על העומסים העודפים האלה מופיעים במאמרי העזרה.
קריאה נוספת
מידע נוסף זמין בדפים הבאים:
- יצירת בקר ניווט
- ניווט ומחסנית החזרה
- ניווט באמצעות אפשרויות
- בטיחות טיפוס ב-Kotlin DSL וב-Navigation Compose