يمثّل الإصدار 3 من Navigation تغييرًا أساسيًا في طريقة تعامل Jetpack Compose مع حالة التنقّل، كما يقدّم مزايا معمارية كبيرة مقارنةً بالإصدار 2 من Navigation.
التعرّف على التغييرات في التصميم والخطوات المطلوبة لنقل تطبيق Wear Compose من الإصدار 2 إلى الإصدار 3 من Navigation
المزايا الرئيسية في Navigation 3
- التحكّم المباشر في حزمة الخلف: إنّ
NavBackStackهي في الأساس مجرد قائمة قابلة للتغيير من عناصرNavKey، وتمثّل سجلّ الشاشات التي زارها المستخدم. يمكنك التحكّم في هذه القائمة تمامًا كما تفعل مع أيMutableListفي Kotlin (addوremoveLastوclear). ويمكنك تعديل القائمة مباشرةً لتنفيذ إجراءات التنقّل، مثل إضافة مفتاح للانتقال إلى الأمام أو إزالة مفتاح للرجوع إلى الخلف. - التصميم المستند إلى Compose: يتم تصميم سجلّ الرجوع على أنّه حالة عادية قابلة للملاحظة. يتم تعديل سجلّ التنقّل بالطريقة نفسها التي يتم بها تعديل أي حالة أخرى في Compose، ما يؤدي تلقائيًا إلى إعادة التركيب لعرض الشاشة الحالية.
- آمنة الأنواع تلقائيًا: يتم إلغاء المسارات المستندة إلى السلاسل بالكامل. تستخدِم Navigation عناصر بيانات وفئات بيانات قابلة للتسلسل.
- العروض التقديمية المنفصلة (استراتيجيات المشاهد): تم فصل طبقة انتقال واجهة المستخدم (
NavDisplayوSwipeDismissableSceneStrategy) بالكامل عن تتبُّع الحالة (NavBackStack)، ما يتيح دمجًا أبسط لعمليات الانتقال المضمّنة في Wear OS.
خطوات نقل البيانات
1. تعديل التبعيات
أزلنا التبعية القديمة androidx.wear.compose:compose-navigation وأضفنا تبعيات Navigation 3 الجديدة المقسّمة، بالإضافة إلى إتاحة استخدام Kotlin Serialization.
الإزالة:
implementation("androidx.wear.compose:compose-navigation:...")
إضافة:
implementation("androidx.navigation3:navigation3-runtime:...") // State logic
implementation("androidx.navigation3:navigation3-ui:...") // Display logic
implementation("androidx.wear.compose:compose-navigation3:...") // Wear gestures
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:...") // Requires compiler plugin
2. تعديل الوجهات لتنفيذ NavKey
في Navigation 2، ربما استخدمت سلاسل أو عناصر عامة للتوجيه. في Navigation 3، يجب تنفيذ واجهة العلامة NavKey وإضافة التعليق التوضيحي @Serializable إلى كل عنصر شاشة.
لماذا هذا الإجراء مطلوب؟ لضمان إمكانية حفظ الأنشطة السابقة واستعادتها عند إيقاف العملية نهائيًا، تعتمد navigation3-runtime الأساسية على kotlinx-serialization لتسلسل الحالة.
قبل (Navigation 2 - Generic Type-Safe Routes):
sealed class Nav2Screen { data object Landing : Nav2Screen() data object List : Nav2Screen() }
After (Navigation 3 - NavKey + Serializable):
@Serializable sealed interface MigrationScreen : NavKey { @Serializable data object Landing : MigrationScreen @Serializable data object List : MigrationScreen }
3- استبدال منطق التوجيه (NavController بـ NavBackStack)
استبدِل NavController بـ NavBackStack تم إعداده باستخدام rememberNavBackStack. عليك أيضًا إنشاء مثيل للفئة
SwipeDismissableSceneStrategy خصيصًا لنظام التشغيل Wear OS.
قبل (التنقل 2):
val navController = rememberSwipeDismissableNavController()
بعد (التنقل 3):
val backStack = rememberNavBackStack(MigrationScreen.Landing as NavKey) val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()
4. استبدِل NavHost بـ NavDisplay وentryProvider DSL
يتم استبدال الحاوية NavHost وأداة الإنشاء الداخلية composable("route") { ... }
DSL بـ NavDisplay وentryProvider {
entry<Key> { ... } } DSL.
قبل (التنقل 2):
SwipeDismissableNavHost(navController = navController, startDestination = "menu") { composable("menu") { GreetingScreen( onShowList = { navController.navigate("list") } ) } composable("list") { ListScreen() } }
بعد (التنقل 3):
NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryProvider = entryProvider { entry<MigrationScreen.Landing> { GreetingScreen( onShowList = { backStack.add(MigrationScreen.List) } ) } entry<MigrationScreen.List> { ListScreen() } } )