ניווט ליעד

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

במדריך הזה מוסבר איך להשתמש ברכיב 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().

דוגמה לכך מופיעה בסעיף המשנה הבא.

דוגמה

כדי להמחיש את מה שמוסבר בקטעים הקודמים, אפשר לראות את הנקודות האלה בקטע הקוד הבא:

  1. כל יעד בתרשים נוצר באמצעות נתיב, שהוא אובייקט או מחלקה שניתנים לסריאליזציה ומתארים את הנתונים שנדרשים ליעד הזה.
  2. הרכיב הקומפוזבילי MyAppNavHost מחזיק את המופע של NavController.
  3. לכן, קריאות ל-navigate() צריכות להתרחש שם ולא ברכיב composable נמוך יותר כמו ProfileScreen.
  4. ProfileScreen מכיל לחצן שמוביל את המשתמש אל FriendsList כשהוא לוחץ עליו. עם זאת, הוא לא קורא ל-navigate() בעצמו.
  5. במקום זאת, הכפתור קורא לפונקציה שמוצגת כפרמטר onNavigateToFriends.
  6. כש-MyAppNavHost מוסיף את ProfileScreen לתרשים הניווט, הוא מעביר ל-onNavigateToFriends פונקציית למדה שקוראת ל-navigate(route = FriendsList).
  7. כך מוודאים שכשהמשתמש לוחץ על הכפתור 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);
  }
});

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

ניווט מ-Compose באפליקציה מבוססת-Fragment

אם אתם משתמשים ב-Jetpack Compose בארכיטקטורת ניווט מבוססת-מקטע (למשל, באפליקציה מעורבת של Views ו-Compose), אתם לא יכולים להשתמש במסלולי Compose בטוחים-סוג כדי לנווט ישירות. במקום זאת, צריך להשתמש במזהים שלמים (פעולות) שמוגדרים בתרשים הניווט של ה-XML.

כדי לשנות את יעדי ההפניה מקוד ה-Compose, חושפים אירוע (lambda) מהקומפוזיציה:

@Composable
fun MyScreen(onNavigateToProfile: () -> Unit) {
    Button(onClick = { onNavigateToProfile() }) {
        Text("Go to Profile")
    }
}

במקטע, מגשרים בין Compose לבין רכיב הניווט מבוסס-מקטע על ידי קריאה ל-NavController של המקטע כשהאירוע מופעל:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    return ComposeView(requireContext()).apply {
        setContent {
            MyScreen(onNavigateToProfile = { findNavController().navigate(R.id.nav_profile) })
        }
    }
}

הגישה הזו מאפשרת לכם להשתמש מחדש ברכיבי ה-Composable ולבדוק אותם, כי הם לא תלויים ישירות ב-NavController של ה-Fragment.

ניווט באמצעות 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. פרטים נוספים על העומסים העודפים האלה מופיעים במאמרי העזרה.

קריאה נוספת

מידע נוסף זמין בדפים הבאים: