Navigation Compose API מאפשר לכם לנווט בין רכיבים קומפוזביליים באפליקציית פיתוח נייטיב, תוך ניצול הרכיב, התשתית והתכונות של Jetpack Navigation.
בדף הזה מוסבר איך לעבור מ-Jetpack Navigation מבוסס-מקטע (fragment) ל-Navigation Compose, כחלק מהמעבר הגדול יותר מממשק משתמש מבוסס-תצוגה ל-Jetpack Compose.
דרישות מוקדמות להעברה
אפשר לעבור אל Navigation Compose אחרי שמחליפים את כל המקטעים (fragments) ברכיבי Composable מקבילים ברמת המסך. רכיבי Composable של מסכים יכולים להכיל שילוב של תוכן פיתוח נייטיב ותוכן View, אבל כל יעדי הניווט חייבים להיות רכיבי Composable כדי לאפשר העברה של Navigation Compose. עד אז, כדאי להמשיך להשתמש ברכיב הניווט מבוסס-מקטע (fragment) בבסיס הקוד של View ופיתוח נייטיב עם יכולת פעולה הדדית. מידע נוסף זמין במסמכי התיעוד בנושא יכולת פעולה הדדית של ניווט.
שלבי ההעברה
לא משנה אם אתם פועלים לפי אסטרטגיית ההעברה המומלצת שלנו או נוקטים גישה אחרת, תגיעו לנקודה שבה כל יעדי הניווט הם רכיבי Composable של מסכים, והמקטעים (fragments) פועלים רק כמארזים של רכיבי Composable. בשלב הזה, אתם יכולים לעבור ל-Navigation Compose.
אם האפליקציה כבר פועלת לפי תבנית עיצוב של UDF והמדריך שלנו לארכיטקטורה, המעבר ל-Jetpack Compose ול-Navigation Compose לא אמור לדרוש שינויים משמעותיים בשכבות אחרות של האפליקציה, מלבד שכבת ממשק המשתמש.
כדי לעבור ל-Navigation Compose, פועלים לפי השלבים הבאים:
- מוסיפים לאפליקציה את התלות של Navigation Compose.
יוצרים פונקציה קומפוזבילית של
App-levelומוסיפים אותה ל-Activityכנקודת הכניסה של Compose, במקום ההגדרה של פריסת התצוגה:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
יוצרים סוגים לכל יעד ניווט. משתמשים ב-
data objectליעדים שלא דורשים נתונים, וב-data classאו ב-classליעדים שדורשים נתונים.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
מגדירים את
NavControllerבמקום שבו לכל הפונקציות הניתנות לקישור שצריכות להפנות אליו יש גישה אליו (בדרך כלל בתוך הפונקציה הניתנת לקישורApp). הגישה הזו פועלת לפי העקרונות של העלאת הרמה של מצב (state hoisting) ומאפשרת להשתמש ב-NavControllerכמקור האמת לניווט בין מסכים קומפוזביליים ולתחזוקה של מקבץ הפעילויות הקודמות (back stack):@Composable fun SampleApp() { val navController = rememberNavController() // ... }
יוצרים את
NavHostשל האפליקציה בתוך הפונקציה הקומפוזבילית שלAppומעבירים אתnavController:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
מוסיפים את
composableהיעדים כדי ליצור את תרשים הניווט. אם כל מסך כבר הועבר לפיתוח נייטיב, השלב הזה כולל רק חילוץ של רכיבי ה-Composable של המסכים האלה מה-Fragments אל היעדים שלcomposable:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
אם פעלתם לפי ההנחיות לתכנון ממשק המשתמש של Compose, ובמיוחד לגבי האופן שבו צריך להעביר את ה-
ViewModelואירועי הניווט לפונקציות ה-Composable, השלב הבא הוא לשנות את האופן שבו אתם מספקים את ה-ViewModelלכל פונקציית Composable של מסך. לרוב אפשר להשתמש בהחדרה של Hilt ובנקודת השילוב שלה עם פיתוח נייטיב ו-Navigation באמצעותhiltViewModel:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
מחליפים את כל הקריאות לניווט ב-
findNavController()בקריאות ב-navControllerומעבירים אותן כאירועי ניווט לכל מסך קומפוזבילי, במקום להעביר את כל ה-navController. הגישה הזו תואמת לשיטות המומלצות לחשיפת אירועים מפונקציות קומפוזביליות למבצעי הקריאות, ושומרת עלnavControllerכמקור האמת היחיד (SSOT).כדי להעביר נתונים ליעד, אפשר ליצור מופע של מחלקת המסלול שמוגדרת ליעד הזה. אחר כך אפשר לקבל אותו ישירות מהרשומה של מקבץ הפעילויות הקודמות ביעד, או מ-
ViewModelבאמצעותSavedStateHandle.toRoute().@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
מסירים את כל המקטעים (fragments), פריסות ה-XML הרלוונטיות, הניווט המיותר ומשאבים אחרים, וגם את יחסי התלות המיושנים של המקטעים ושל Jetpack Navigation.
אפשר למצוא את אותם השלבים עם פרטים נוספים שקשורים ל-Navigation Compose במסמכי התיעוד בנושא הגדרה.
תרחישים נפוצים לדוגמה
לא משנה באיזה רכיב Navigation אתם משתמשים, חלים אותם עקרונות ניווט.
תרחישים נפוצים לדוגמה במהלך ההעברה:
- ניווט אל פונקציה קומפוזבילית
- ניווט באמצעות ארגומנטים
- קישורי עומק
- ניווט בתצוגת עץ
- שילוב עם סרגל הניווט התחתון
- שילוב עם רכיב ניווט בהתאמה אישית
מידע מפורט יותר על תרחישי השימוש האלה זמין במאמר ניווט באמצעות Compose.
אחזור נתונים מורכבים במהלך הניווט
מומלץ מאוד לא להעביר אובייקטים מורכבים של נתונים במהלך הניווט. במקום זאת, העבירו את המידע המינימלי הדרוש, כמו מזהה ייחודי או סוג אחר של מזהה, כארגומנטים כשאתם מבצעים פעולות ניווט. כדאי לאחסן אובייקטים מורכבים כנתונים במקור אמת יחיד (SSOT), כמו שכבת הנתונים. מידע נוסף זמין במאמר אחזור נתונים מורכבים במהלך ניווט.
אם ה-Fragments מעבירים אובייקטים מורכבים כארגומנטים, כדאי קודם לארגן את הקוד מחדש כך שיהיה אפשר לאחסן את האובייקטים האלה בשכבת הנתונים ולאחזר אותם ממנה. דוגמאות לכך אפשר לראות במאגר Now in Android.
מגבלות
בקטע הזה מתוארות המגבלות הנוכחיות של Navigation Compose.
העברה הדרגתית ל-Navigation Compose
נכון לעכשיו, אי אפשר להשתמש ב-Navigation Compose כשעדיין משתמשים במקטעים (fragments) כיעדים בקוד. כדי להתחיל להשתמש ב-Navigation Compose, כל היעדים צריכים להיות פונקציות קומפוזביליות. אתם יכולים לעקוב אחרי הגשת בקשה להוספת תכונה ב-Issue Tracker.
אנימציות מעבר
החל מגרסה Navigation 2.7.0-alpha01, התמיכה בהגדרת מעברים בהתאמה אישית, שהייתה בעבר מ-AnimatedNavHost, נתמכת עכשיו ישירות ב-NavHost. למידע נוסף, קראו את נתוני הגרסה.
מידע נוסף
מידע נוסף על המעבר ל-Navigation Compose זמין במקורות המידע הבאים:
- Codelab בנושא Navigation Compose: ב-codelab הזה מוסבר על היסודות של Navigation Compose.
- מאגר Now in Android: אפליקציה ל-Android שפועלת באופן מלא, שנוצרה לגמרי באמצעות Kotlin ו-Jetpack Compose, שפועלת לפי השיטות המומלצות לעיצוב ולפיתוח ב-Android וכוללת את Navigation Compose.
- העברת Sunflower ל-Jetpack Compose: פוסט בבלוג שמתעד את תהליך ההעברה של האפליקציה לדוגמה Sunflower מ-Views ל-Compose, כולל העברה ל-Navigation Compose.
- Jetnews לכל מסך: פוסט בבלוג שמתעד את ה-refactor וההעברה של Jetnews לדוגמה כדי לתמוך בכל המסכים באמצעות Jetpack Compose ו-Navigation Compose.
מומלץ בשבילכם
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- ניווט באמצעות "פיתוח נייטיב"
- Compose וספריות אחרות
- עוד דברים שכדאי לבדוק