Navigation Compose API מאפשר לכם לנווט בין קומפוזיציות באפליקציית Compose, תוך ניצול היתרונות של רכיב Jetpack Navigation, התשתית והתכונות שלו.
בדף הזה מוסבר איך לבצע מיגרציה מ-Jetpack Navigation מבוסס-Fragment ל-Navigation Compose, כחלק מהמיגרציה הגדולה יותר של ממשק משתמש מבוסס-View ל-Jetpack Compose.
תנאים מוקדמים להעברה
אפשר לעבור אל Navigation Compose אחרי שמחליפים את כל ה-Fragments ברכיבי מסך תואמים שניתנים להרכבה. רכיבי מסך מסוג Composable יכולים להכיל שילוב של תוכן Compose ותוכן View, אבל כל יעדי הניווט חייבים להיות רכיבים מסוג Composable כדי לאפשר העברה של Navigation Compose. עד אז, כדאי להמשיך להשתמש ברכיב הניווט מבוסס-Fragment בבסיס הקוד של View ו-Compose. מידע נוסף זמין במאמרי העזרה בנושא תאימות בין מערכות ניווט.
לא צריך להשתמש ב-Navigation Compose באפליקציה שמבוססת על Compose בלבד. אתם יכולים להמשיך להשתמש ברכיב הניווט מבוסס-Fragment, כל עוד אתם משתמשים ב-Fragments כדי לארח את התוכן שניתן להרכבה.
שלבים בהעברה
גם אם אתם פועלים לפי אסטרטגיית ההעברה המומלצת שלנו וגם אם אתם נוקטים גישה אחרת, תגיעו למצב שבו כל יעדי הניווט הם קומפוזיציות של מסכים, ורכיבי Fragment משמשים רק כקונטיינרים של קומפוזיציות. בשלב הזה, אפשר לבצע מיגרציה ל-Navigation Compose.
אם האפליקציה כבר פועלת לפי דפוס עיצוב של UDF ובהתאם למדריך שלנו בנושא ארכיטקטורה, המעבר ל-Jetpack Compose ול-Navigation Compose לא אמור לדרוש שינויים משמעותיים בשכבות אחרות של האפליקציה, מלבד שכבת ממשק המשתמש.
כדי לבצע מיגרציה ל-Navigation Compose, פועלים לפי השלבים הבאים:
- מוסיפים את התלות של Navigation Compose לאפליקציה.
יוצרים רכיב
App-level
שאפשר להרכיב ומוסיפים אותו ל-Activity
כנקודת הכניסה שלכם לכתיבת הודעות, במקום ההגדרה של פריסת התצוגה: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
). הגישה הזו מבוססת על העקרונות של העברת מצב ומאפשרת להשתמש ב-NavController
כמקור האמת לניווט בין מסכים שאפשר להוסיף להם קומפוננטות ולשמירה על היסטוריית החזרה:@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
כדי ליצור את גרף הניווט. אם כל מסך הועבר בעבר ל-Compose, השלב הזה כולל רק חילוץ של רכיבי ה-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 ובנקודת השילוב שלה עם Compose ו-Navigation באמצעותhiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
מחליפים את כל הקריאות לניווט
findNavController()
בקריאותnavController
ומעבירים אותן כאירועי ניווט לכל מסך שניתן להרכבה, במקום להעביר את כלnavController
. הגישה הזו תואמת לשיטות המומלצות לחשיפת אירועים מפונקציות שאפשר להרכיב למתקשרים, ושומרת עלnavController
כמקור המהימן היחיד.אפשר להעביר נתונים ליעד על ידי יצירת מופע של מחלקת המסלול שהוגדרה ליעד הזה. אפשר לקבל אותו ישירות מהערך במחסנית החזרה ביעד או מ-
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 הרלוונטיות, רכיבי הניווט המיותרים ומשאבים אחרים, וכן רכיבים תלויים ישנים של Fragment ו-Jetpack Navigation.
במסמכי ההגדרה מפורטים אותם השלבים עם פרטים נוספים שקשורים ל-Navigation Compose.
תרחישים נפוצים לדוגמה
לא משנה באיזה רכיב ניווט משתמשים, אותם עקרונות ניווט חלים.
תרחישים נפוצים להעברה:
- ניווט אל קומפוזבל
- ניווט באמצעות ארגומנטים
- קישורי עומק
- ניווט מוטמע
- שילוב עם סרגל הניווט התחתון
- שילוב עם רכיב ניווט בהתאמה אישית
מידע מפורט יותר על תרחישי השימוש האלה זמין במאמר ניווט באמצעות כתיבת הודעות.
אחזור נתונים מורכבים במהלך הניווט
מומלץ מאוד להימנע מהעברת אובייקטים מורכבים של נתונים במהלך הניווט. במקום זאת, כשמבצעים פעולות ניווט, מעבירים את המידע המינימלי הנדרש כארגומנטים, כמו מזהה ייחודי או סוג אחר של מזהה. מומלץ לאחסן אובייקטים מורכבים כנתונים במקור אחד לנתוני האמת, כמו שכבת הנתונים. מידע נוסף זמין במאמר אחזור נתונים מורכבים במהלך הניווט.
אם רכיבי ה-Fragment מעבירים אובייקטים מורכבים כארגומנטים, כדאי לשנות את מבנה הקוד כך שיהיה אפשר לאחסן את האובייקטים האלה בשכבת הנתונים ולאחזר אותם ממנה. דוגמאות לכך אפשר לראות במאגר Now in Android.
מגבלות
בקטע הזה מתוארות המגבלות הנוכחיות של Navigation Compose.
העברה מצטברת ל-Navigation Compose
בשלב הזה, אי אפשר להשתמש ב-Navigation Compose כשעדיין משתמשים ב-Fragments כיעדים בקוד. כדי להתחיל להשתמש ב-Navigation Compose, כל היעדים צריכים להיות פונקציות שאפשר להוסיף לקומפוזיציה. אפשר לעקוב אחרי הבקשה הזו לתכונה בכלי למעקב אחר בעיות.
אנימציות של מעברים
החל מגרסה Navigation 2.7.0-alpha01, התמיכה בהגדרת מעברים מותאמים אישית, שבעבר הייתה זמינה מ-AnimatedNavHost
, זמינה עכשיו ישירות ב-NavHost
. מידע נוסף זמין בהערות המוצר.
מידע נוסף
למידע נוסף על מעבר ל-Navigation Compose, אפשר לעיין במקורות המידע הבאים:
- Navigation Compose codelab: לומדים את היסודות של Navigation Compose באמצעות codelab מעשי.
- מאגר Now in Android: אפליקציית Android פונקציונלית לחלוטין שנבנתה לגמרי באמצעות Kotlin ו-Jetpack Compose, בהתאם לשיטות המומלצות לעיצוב ולפיתוח של Android, וכוללת Navigation Compose.
- העברת Sunflower ל-Jetpack Compose: פוסט בבלוג שמתעד את תהליך ההעברה של אפליקציית הדוגמה Sunflower מ-Views ל-Compose, שכולל גם העברה ל-Navigation Compose.
- Jetnews for every screen: פוסט בבלוג שמתעד את הריפקטורינג וההעברה של דוגמת Jetnews כדי לתמוך בכל המסכים באמצעות Jetpack Compose ו-Navigation Compose.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- ניווט באמצעות התכונה 'יצירה'
- Compose וספריות אחרות
- שיקולים נוספים