مهاجرت به ناوبری ۳

ناوبری ۳ نشان‌دهنده‌ی یک تغییر اساسی در نحوه‌ی مدیریت وضعیت ناوبری توسط Jetpack Compose است و مزایای معماری قابل توجهی نسبت به ناوبری ۲ ارائه می‌دهد.

تغییرات معماری و مراحل مورد نیاز برای مهاجرت یک برنامه Wear Compose از Navigation 2 به Navigation 3 را درک کنید.

مزایای کلیدی ناوبری ۳

  • کنترل مستقیم Back Stack : NavBackStack اساساً فقط یک لیست قابل تغییر از اشیاء NavKey است که تاریخچه صفحات بازدید شده توسط کاربر را نشان می‌دهد. شما آن را دقیقاً مانند هر MutableList کاتلین ( add ، removeLast ، clear ) کنترل می‌کنید. شما مستقیماً لیست را برای انجام اقدامات ناوبری، مانند اضافه کردن یک کلید برای رفتن به جلو یا حذف یک کلید برای برگشت، دستکاری می‌کنید.
  • طراحی با اولویت ترکیب (Compose-First) : پشته پشتی به عنوان یک حالت استاندارد قابل مشاهده مدل‌سازی می‌شود. تغییر تاریخچه ناوبری شما دقیقاً مانند به‌روزرسانی هر حالت ترکیب دیگری رفتار می‌کند و به طور خودکار ترکیب مجدد را برای نمایش صفحه فعلی فعال می‌کند.
  • پیش‌فرض از نوع داده ایمن : مسیرهای مبتنی بر رشته به طور کامل حذف می‌شوند. ناوبری از اشیاء داده و کلاس‌های داده قابل سریال‌سازی استفاده می‌کند.
  • ارائه‌های جدا (استراتژی‌های صحنه) : لایه انتقال رابط کاربری ( NavDisplay و SwipeDismissableSceneStrategy ) کاملاً از ردیابی حالت ( NavBackStack ) جدا شده است و امکان ادغام ساده‌تر انتقال‌های ناوبری داخلی Wear OS را فراهم می‌کند.

مراحل مهاجرت

۱. به‌روزرسانی وابستگی‌ها

وابستگی قدیمی androidx.wear.compose:compose-navigation را حذف کرده و وابستگی‌های جدید split Navigation 3 را به همراه پشتیبانی از سریال‌سازی کاتلین معرفی کنید.

حذف:

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

۲. به‌روزرسانی مقصدها برای پیاده‌سازی NavKey

در ناوبری ۲، ممکن است از رشته‌ها یا اشیاء عمومی برای مسیریابی استفاده کرده باشید. در ناوبری ۳، باید رابط نشانگر NavKey را پیاده‌سازی کنید و هر شیء صفحه را با @Serializable حاشیه‌نویسی کنید.

چرا این مورد نیاز است؟ برای تضمین اینکه پشته پشتی می‌تواند در طول مرگ فرآیند ذخیره و بازیابی شود، navigation3-runtime زیرین برای سریال‌سازی حالت به kotlinx-serialization متکی است.

قبل از (ناوبری ۲ - مسیرهای عمومی ایمن از نوع):

sealed class Nav2Screen {
    data object Landing : Nav2Screen()
    data object List : Nav2Screen()
}

بعد از (پیمایش ۳ - کلید ناوبری + قابلیت سریال‌سازی):

@Serializable
sealed interface MigrationScreen : NavKey {
    @Serializable
    data object Landing : MigrationScreen

    @Serializable
    data object List : MigrationScreen
}

۳. منطق مسیریابی ( NavController را به NavBackStack ) تغییر دهید.

NavController خود را با یک NavBackStack که از طریق rememberNavBackStack مقداردهی اولیه شده است، جایگزین کنید. همچنین باید SwipeDismissableSceneStrategy را به طور خاص برای Wear OS نمونه‌سازی کنید.

قبل (پیمایش ۲):

val navController = rememberSwipeDismissableNavController()

بعد از (پیمایش ۳):

val backStack = rememberNavBackStack(MigrationScreen.Landing as NavKey)
val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()

۴. NavHost با NavDisplay و entryProvider DSL جایگزین کنید.

کانتینر NavHost و سازنده‌ی داخلی آن composable("route") { ... } یعنی DSL، با NavDisplay و entryProvider { entry<Key> { ... } } DSL جایگزین می‌شوند.

قبل (پیمایش ۲):

SwipeDismissableNavHost(navController = navController, startDestination = "menu") {
    composable("menu") {
        GreetingScreen(
            onShowList = { navController.navigate("list") }
        )
    }
    composable("list") {
        ListScreen()
    }
}

بعد از (پیمایش ۳):

NavDisplay(
    backStack = backStack,
    sceneStrategies = listOf(strategy),
    entryProvider = entryProvider {
        entry<MigrationScreen.Landing> {
            GreetingScreen(
                onShowList = { backStack.add(MigrationScreen.List) }
            )
        }
        entry<MigrationScreen.List> {
            ListScreen()
        }
    }
)