مهارتهای Android
مشاهده در GitHubJetpack Navigation 3
android skills add navigation-3برای انتقال برنامهتان از Navigation 2 به Navigation 3، این مراحل را دنبال کنید:
- وابستگیهای Navigation 3 را اضافه کنید.
- مسیرهای پیمایش را بهروز کنید تا میانای
NavKeyرا پیادهسازی کنید. - کلاسهایی برای نگهداری و اصلاح وضعیت ناوبری ایجاد کنید.
NavControllerرا با این کلاسها جایگزین کنید.- مقصدهایتان را از
NavGraphNavHostبهentryProviderمنتقل کنید. NavHostرا باNavDisplayجایگزین کنید.- وابستگیهای Navigation 2 را بردارید.
آمادهسازی
بخشهای زیر پیشنیازهای انتقال و فرضیات مربوط به پروژه شما را شرح میدهند. همچنین ویژگیهایی را که برای انتقال پشتیبانی میشوند و ویژگیهایی را که پشتیبانی نمیشوند پوشش میدهند.
پیشنیازها
- باید از
compileSdkنسخه ۳۶ یا جدیدتر استفاده کنید. - باید با اصطلاحات پیمایش آشنا باشید.
- مقصدها توابع ترکیبپذیر هستند. Navigation 3 منحصراً برای Compose طراحی شده است. برای استفاده از Fragments و Views در Compose، به استفاده از Views در Compose مراجعه کنید.
- مسیرها بهشدت تایپ میشوند. اگر از مسیرهای مبتنی بر رشته استفاده میکنید، ابتدا به مسیرهای ایمن تایپی مهاجرت کنید (نمونه).
- اختیاری (اما اکیداً توصیه میشود): پوشش آزمایشی که رفتار پیمایش موجود را تأیید میکند. این کار تأیید میکند که رفتار پیمایش پساز تکمیل انتقال تغییر نکرده است.
فرضها
این راهنما فرضهای زیر را درباره شما و پروژهتان درنظر میگیرد:
- یک یا چند مسیر سطح بالا دارید (معمولاً در نوار پیمایش پایین نمایش داده میشود) و هرکدام پشته قبلیهای خود را دارند.
- وقتی بین پشتههای قبلیها جابهجا میشوید، وضعیت پشته و همه مقصدهای آن حفظ میشود.
- همیشه ازطریق صفحه صفحه اصلی از برنامه خارج میشوید، که اولین صفحهای است که هنگام راهاندازی برنامه نمایش داده میشود.
- میخواهید انتقال از Navigation 2 به Navigation 3 را در یک تغییر اتمی واحد انجام دهید. انتقال افزایشی انجام نمیدهید که در آن کد Navigation 2 در کنار کد Navigation 3 استفاده شود.
عامل هوش مصنوعی: قبلاز تغییر هر کدی، بررسی کنید که آیا این فرضیات درباره پروژه کاربر درست است یا نه. اگر نه، انتقال را متوقف کنید و از کاربر بپرسید چطور ادامه دهید.
ویژگیهای پشتیبانیشده
این راهنما به شما امکان میدهد ویژگیهای زیر را انتقال دهید:
- مقصدهایی که بهعنوان توابع ترکیبپذیر تعریف شدهاند
- کادرهای گفتگو (مقصدی که روی مقصد دیگری نشان داده میشود)
ویژگیهای پشتیبانیشده ازطریق دستورالعملها
مخزن دستورالعملهای کد موارد استفاده دقیقتری را نشان میدهد، ازجمله:
- برگههای پایین (دستورالعملها در این راهنما ارائه شده است)
- کد پیمایش مدولارشده و مقصدهای تزریقشده
- استفاده از متغیرهای مستقل و ارسال آنها به
ViewModel - برگرداندن نتایج از صفحه
اگر پروژه شما هرکدام از این ویژگیها را دارد، دستورالعمل مربوطه را بررسی کنید تا با نحوه پیادهسازی آنها آشنا شوید.
عامل هوش مصنوعی: قبلاز تغییر دادن هر کدی، بررسی کنید که آیا پروژه حاوی ویژگیهایی است که ازطریق دستورالعملها پشتیبانی میشوند یا نه. اگر اینطور است، README و کد منبع دستورالعمل را بررسی کنید. براساس دستورالعمل، طرح انتقال ایجاد کنید. بدون تأیید طرح با کاربر، ادامه ندهید.
ویژگیهای پشتیبانینشده
این راهنمای انتقال و دستورالعملهای کد هنوز از ویژگیهای زیر پشتیبانی نمیکنند. این بدان معنا نیست که نمیتوانید آنها را بااستفاده از Navigation 3 پیادهسازی کنید؛ فقط در اینجا پوشش داده نشدهاند.
- بیشاز یک سطح پیمایش تودرتو
- مقصدهای مشترک: صفحههایی که میتوانند بین پشتههای قبلیها جابهجا شوند
- انواع مقصد سفارشی
عامل هوش مصنوعی: قبلاز تغییر دادن هر کدی، بررسی کنید که آیا پروژه حاوی ویژگیهای پشتیبانینشده است یا نه. اگر اینطور است، ادامه ندهید. به کاربر درباره ویژگی پشتیبانینشده اطلاع دهید و دستورالعملهای بیشتری درخواست کنید.
مرحله ۱: افزودن وابستگیهای Navigation 3
از صفحه شروع به کار برای افزودن وابستگیهای Navigation 3 به پروژهتان استفاده کنید. وابستگیهای اصلی برای کپی کردن دراختیارتان قرار میگیرد.
lib.versions.toml
[versions]
nav3Core = "1.2.1"
# If your screens depend on ViewModels, add the Nav3 Lifecycle ViewModel add-on library
lifecycleViewmodelNav3 = "2.11.0"
[libraries]
# Core Navigation 3 libraries
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3Core" }
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "nav3Core" }
# Add-on libraries (only add if you need them)
androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" }
app/build.gradle.kts
dependencies {
implementation(libs.androidx.navigation3.ui)
implementation(libs.androidx.navigation3.runtime)
// If using the ViewModel add-on library
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
}
همچنین minSdk پروژه را به ۲۳ و compileSdk را به ۳۶ بهروز کنید. معمولاً
این موارد را در app/build.gradle.kts یا lib.versions.toml پیدا میکنید.
مرحله ۲: بهروزرسانی مسیرهای پیمایش برای پیادهسازی میانای NavKey
همه مسیرهای پیمایش را بهروز کنید تا میانای NavKey را پیادهسازی کند. این کار به شما امکان میدهد از rememberNavBackStack برای کمک به ذخیره کردن
وضعیت پیمایش استفاده کنید.
قبلاز:
@Serializable data object RouteA
بعداز:
@Serializable data object RouteA : NavKey
مرحله ۳: ایجاد کلاسهایی برای نگهداری و اصلاح وضعیت پیمایش
مرحله ۳.۱: ایجاد نگهدارنده حالت پیمایش
کد زیر را در فایلی با نام NavigationState.kt کپی کنید. نام بستهتان را اضافه کنید
تا با ساختار پروژهتان مطابقت داشته باشد.
// package com.example.project import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSerializable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.toMutableStateList import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavEntry import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.rememberDecoratedNavEntries import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator import androidx.navigation3.runtime.serialization.NavKeySerializer import androidx.savedstate.compose.serialization.serializers.MutableStateSerializer /** * Create a navigation state that persists config changes and process death. */ @Composable fun rememberNavigationState( startRoute: NavKey, topLevelRoutes: Set<NavKey> ): NavigationState { val topLevelRoute = rememberSerializable( startRoute, topLevelRoutes, serializer = MutableStateSerializer(NavKeySerializer()) ) { mutableStateOf(startRoute) } val backStacks = topLevelRoutes.associateWith { key -> rememberNavBackStack(key) } return remember(startRoute, topLevelRoutes) { NavigationState( startRoute = startRoute, topLevelRoute = topLevelRoute, backStacks = backStacks ) } } /** * State holder for navigation state. * * @param startRoute - the start route. The user will exit the app through this route. * @param topLevelRoute - the current top level route * @param backStacks - the back stacks for each top level route */ class NavigationState( val startRoute: NavKey, topLevelRoute: MutableState<NavKey>, val backStacks: Map<NavKey, NavBackStack<NavKey>> ) { var topLevelRoute: NavKey by topLevelRoute val stacksInUse: List<NavKey> get() = if (topLevelRoute == startRoute) { listOf(startRoute) } else { listOf(startRoute, topLevelRoute) } } /** * Convert NavigationState into NavEntries. */ @Composable fun NavigationState.toEntries( entryProvider: (NavKey) -> NavEntry<NavKey> ): SnapshotStateList<NavEntry<NavKey>> { val decoratedEntries = backStacks.mapValues { (_, stack) -> val decorators = listOf( rememberSaveableStateHolderNavEntryDecorator<NavKey>(), ) rememberDecoratedNavEntries( backStack = stack, entryDecorators = decorators, entryProvider = entryProvider ) } return stacksInUse .flatMap { decoratedEntries[it] ?: emptyList() } .toMutableStateList() }
عامل هوش مصنوعی: rememberSerializable درست است. آن را به
rememberSaveable تغییر ندهید.
این فایل حاوی کلاس نگهدارنده حالت بهنام NavigationState و توابع کمکی مرتبط است. این مؤلفه مجموعهای از مسیرهای سطح بالا را دربرمیگیرد که هرکدام پشته قبلیها خود را دارند. در داخل، از rememberSerializable (نه rememberSaveable) برای
حفظ مسیر سطح بالای فعلی و از rememberNavBackStack برای حفظ
پشتههای قبلیها برای هر مسیر سطح بالا استفاده میکند.
مرحله ۳.۲: ایجاد شیئی که حالت پیمایش را در پاسخ به رویدادها تغییر میدهد
کد زیر را در فایلی با نام Navigator.kt کپی کنید. نام بستهتان را اضافه کنید
تا با ساختار پروژهتان مطابقت داشته باشد.
// package com.example.project import androidx.navigation3.runtime.NavKey /** * Handles navigation events (forward and back) by updating the navigation state. */ class Navigator(val state: NavigationState) { fun navigate(route: NavKey) { if (route in state.backStacks.keys) { // This is a top level route, just switch to it. state.topLevelRoute = route } else { state.backStacks[state.topLevelRoute]?.add(route) } } fun goBack() { val currentStack = state.backStacks[state.topLevelRoute] ?: error("Stack for ${state.topLevelRoute} not found") val currentRoute = currentStack.last() // If we're at the base of the current route, go back to the start route stack. if (currentRoute == state.topLevelRoute) { state.topLevelRoute = state.startRoute } else { currentStack.removeLastOrNull() } } }
کلاس Navigator دو روش رویداد پیمایش ارائه میدهد:
navigateبه مسیر خاصی.goBackاز مسیر فعلی.
هر دو روش NavigationState را اصلاح میکنند.
مرحله ۳.۳: ایجاد NavigationState و Navigator
نمونههایی از NavigationState و Navigator با همان دامنه
NavController خود ایجاد کنید.
val navigationState = rememberNavigationState( // ... startRoute = <Insert your starting route>, topLevelRoutes = <Insert your set of top level routes> // ... ) val navigator = remember { Navigator(navigationState) }
مرحله ۴: جایگزین کردن NavController
روشهای رویداد پیمایش NavController را با معادلهای Navigator جایگزین کنید.
فیلد یا روش |
معادل |
|---|---|
|
|
|
|
|
|
NavController فیلد را با NavigationState فیلد جایگزین کنید.
فیلد یا روش |
معادل |
|---|---|
|
|
|
|
|
|
|
|
دریافت مسیر سطح بالا: برای پیدا کردن آن، سلسلهمراتب را از ورودی پشته قبلیها فعلی به بالا پیمایش کنید. |
|
از NavigationState.topLevelRoute برای تعیین موردی که درحالحاضر در نوار پیمایش انتخاب شده است استفاده کنید.
قبلاز:
// ... val isSelected = navController.currentBackStackEntryAsState().value?.destination.isRouteInHierarchy(key::class) // ... fun NavDestination?.isRouteInHierarchy(route: KClass<*>) = this?.hierarchy?.any { it.hasRoute(route) } ?: false
بعداز:
val isSelected = key == navigationState.topLevelRoute
تأیید کنید که همه ارجاعها به NavController، ازجمله
هرگونه واردات را برداشتهاید.
مرحله ۴.۱ انتقال منطق آگاه از چرخه حیات
در Navigation 2، NavBackStackEntry LifecycleOwner را پیادهسازی میکند و به شما امکان میدهد
بااستفاده از navController.currentBackStackEntry، به رویدادهای چرخه حیات گوش دهید یا جریانها را بهصورت آگاه از چرخه حیات جمعآوری کنید.
در Navigation 3، NavDisplay یک LifecycleOwner با دامنه ورودی
ازطریق LocalLifecycleOwner.current برای محتوای قابلترکیب هر مقصد
ارائه میدهد. برای اطلاعات بیشتر، چرخه حیات مقصد را ببینید.
باید عملیات آگاه از چرخه حیات را مستقیماً در محتوای ترکیبپذیر مقصدتان با ارجاع به LocalLifecycleOwner.current انجام دهید.
برای مثال، اگر جریانی را بهصورت آگاه از چرخه حیات بااستفاده از ورودی پشته قبلیها جمعآوری کنید:
قبلاز:
// In your destination screen or host val lifecycleOwner = navController.currentBackStackEntry!! val state by flow.collectAsStateWithLifecycle(lifecycleOwner = lifecycleOwner)
بعداز:
// Inside the destination composable val state by flow.collectAsStateWithLifecycle()
مرحله ۴.۲ انتقال ارسال نتیجه
در Navigation 2، مقصدها نتایج را بااستفاده از SavedStateHandle در NavBackStackEntry به مقصدهای قبلی برمیگرداندند. Because SavedStateHandle is
backed by saved instance state, returned data survived process death
automatically.
قبلاز:
// Sender destination: navController.previousBackStackEntry?.savedStateHandle?.set("contact_key", contact) navController.popBackStack() // Receiver destination: val lifecycleOwner = LocalLifecycleOwner.current navController.currentBackStackEntry?.savedStateHandle ?.getLiveData<Contact>("contact_key") ?.observe(lifecycleOwner) { contact -> viewModel.onRecipientSelected(contact) }
در «پیمایش ۳»،
rememberResultEventBusNavEntryDecorator() را به
NavDisplay.entryDecorators اضافه کنید. در نگاشت entryProvider مقصد فرستنده، LocalResultEventBus.current را بازیابی کنید و با sendResult() تماس بگیرید. در مقصد دریافتکننده، از
ResultEffect برای بازارسال رویداد به ViewModel یا
راهاندازی عارضه جانبی استفاده کنید.
بعداز:
// Sender destination (in entryProvider): entry<ContactPickerRoute> { val resultBus = LocalResultEventBus.current ContactPickerScreen( onContactSelected = { contact -> resultBus.sendResult<Contact>(result = contact) navigator.goBack() } ) } // Receiver destination: @Composable fun ComposeMessageScreen(viewModel: ComposeMessageViewModel = viewModel()) { ResultEffect<Contact> { contact -> viewModel.onRecipientSelected(contact) } ComposeMessageContent(recipient = viewModel.recipient) }
برای مشاهده حالتمحور، میتوانید resultBus.conflateAsState() را فراخوانی کنید. برای
جزئیات بیشتر، نتایج برگشتی را ببینید.
مرحله ۵: انتقال مقصدها از NavGraph NavHost به entryProvider
در Navigation 2، مقصدهایتان را
بااستفاده از NavGraphBuilder DSL،
معمولاً در داخل لامبدای دنبالهدار NavHost تعریف میکنید. استفاده از توابع افزونه در اینجا، همانطور که در کپسولهسازی کد پیمایش توضیح داده شده است، رایج است.
در Navigation 3، مقصدهایتان را بااستفاده از entryProvider تعریف میکنید. این
entryProvider مسیری را به NavEntry حلوفصل میکند. نکته مهم اینکه
entryProvider روابط والد-فرزند را بین ورودیها تعریف نمیکند.
در این راهنمای انتقال، روابط والد-فرزند بهصورت زیر مدلسازی شده است:
NavigationStateمجموعهای از مسیرهای سطح بالا (مسیرهای والد) و پشتهای برای هرکدام دارد. این کلاس مسیر سطح بالای فعلی و پشته مرتبط با آن را ردیابی میکند.- هنگام پیمایش به مسیر جدید،
Navigatorبررسی میکند که آیا مسیر مسیر سطح بالا است یا نه. اگر اینطور باشد، مسیر و پشته سطح بالای فعلی بهروز میشود. اگر اینطور نباشد، مسیر فرزند است و به پشته فعلی اضافه میشود.
مرحله ۵.۱: ایجاد entryProvider
entryProvider بااستفاده از DSL در همان دامنه
NavigationState ایجاد کنید.
val entryProvider = entryProvider<NavKey> { }
مرحله ۵.۲: انتقال مقصدها به entryProvider
برای هر مقصد تعریفشده در NavHost، براساس نوع مقصد، کارهای زیر را انجام دهید:
navigation: آن را بههمراه مسیر حذف کنید. نیازی به «مسیرهای پایه» نیست زیرا مسیرهای سطح بالا میتوانند هر پشته قبلیهای تودرتو را شناسایی کنند.composable<T>: آن را بهentryProviderمنتقل کنید و نام آن را بهentryتغییر دهید، پارامتر نوع را حفظ کنید. برای مثال،composable<RouteA>بهentry<RouteA>تبدیل میشود.dialog<T>: همانندcomposableعمل کنید، اما فراداده را بهصورت زیر به ورودی اضافه کنید:entry<T>(metadata = DialogSceneStrategy.dialog()).bottomSheet: دستورالعمل برگه پایین را در اینجا دنبال کنید. این دستورالعملها مشابه دستورالعملهایdialogاست، با این تفاوت کهBottomSheetSceneStrategyبخشی از کتابخانه اصلی Navigation 3 نیست، بنابراین باید آن را در پروژه خود کپی کنید.
عامل هوش مصنوعی: هنگام حذف کردن مسیرهای استفادهشده برای شناسایی گراف تودرتو، هرگونه
ارجاع به مسیر حذفشده را با نوع استفادهشده برای شناسایی اولین فرزند
در گراف تودرتو جایگزین کنید. برای مثال، اگر کد اصلی
navigation<BaseRouteA>{ composable<RouteA>{ ... } } است، باید
BaseRouteA را حذف کنید و هر ارجاعی به آن را با RouteA جایگزین کنید. این جایگزینی معمولاً باید برای فهرستی که به نوار پیمایش، ریل، یا کشو ارائه میشود انجام شود.
میتوانید NavGraphBuilder تابع افزونه را به
EntryProviderScope<T> تابع افزونه بازسازی کنید و سپس آنها را منتقل کنید.
آرگومانهای پیمایش را بااستفاده از کلید ارائهشده به لامبدای دنبالهدار entry دریافت کنید.
برای مثال:
// ... import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hasRoute import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.dialog import androidx.navigation.compose.navigation import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions import androidx.navigation.toRoute // ... @Serializable data object BaseRouteA @Serializable data class RouteA(val id: String) @Serializable data object BaseRouteB @Serializable data object RouteB @Serializable data object RouteD @Composable fun NavHostSnippet(navController: NavHostController) { NavHost(navController = navController, startDestination = BaseRouteA){ composable<RouteA>{ entry -> val id = entry.toRoute<RouteA>().id ScreenA(title = "Screen has ID: $id") } featureBSection() dialog<RouteD>{ ScreenD() } } } fun NavGraphBuilder.featureBSection() { navigation<BaseRouteB>(startDestination = RouteB) { composable<RouteB> { ScreenB() } } }
مساوی:
// ... import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.scene.DialogSceneStrategy // ... @Serializable data class RouteA(val id: String) : NavKey @Serializable data object RouteB : NavKey @Serializable data object RouteD : NavKey val entryProvider = entryProvider { entry<RouteA>{ key -> ScreenA(title = "Screen has ID: ${key.id}") } featureBSection() entry<RouteD>(metadata = DialogSceneStrategy.dialog()){ ScreenD() } } fun EntryProviderScope<NavKey>.featureBSection() { entry<RouteB> { ScreenB() } }
مرحله ۶: NavHost را با NavDisplay جایگزین کنید
NavHost را با NavDisplay جایگزین کنید.
NavHostرا حذف کنید و آن را باNavDisplayجایگزین کنید.entries = navigationState.toEntries(entryProvider)را بهعنوان پارامتر مشخص کنید. این کار وضعیت پیمایش را به ورودیهایی تبدیل میکند کهNavDisplayبااستفاده ازentryProviderنشان میدهد.NavDisplay.onBackرا بهnavigator.goBack()متصل کنید. این باعث میشودnavigatorوضعیت ناوبری را وقتی که گرداننده برگشت داخلیNavDisplayتکمیل میشود بهروز کند.- اگر مقصد گفتگو دارید،
DialogSceneStrategyرا به پارامترsceneStrategiesمربوط بهNavDisplayاضافه کنید.
برای مثال:
NavDisplay( entries = navigationState.toEntries(entryProvider), onBack = { navigator.goBack() }, sceneStrategies = remember { listOf(DialogSceneStrategy()) } )
مرحله ۷: انتقال پیوندهای عمیق
در Navigation 2، پیوندهای عمیق مستقیماً در داخل نمودار پیمایش بااستفاده از پارامتر deepLinks مقصدها تعریف میشدند.
در Navigation 3، پیوندهای عمیق مستقل از میانای کاربری پیمایش مدیریت میشوند. شما
DeepLinkMatcher را تعریف میکنید و درخواستهای ورودی را در «فعالیت» خود مطابقت میدهید تا
پشته قبلیهای اولیه را بسازید.
قبلاز:
در Navigation 2، ممکن است پیوند عمیقی مانند این تعریف کرده باشید:
composable<RouteA>( deepLinks = listOf( navDeepLink { uriPattern = "www.example.com/user/{id}" } ) ) { // ... }
بعداز:
در Navigation 3، یک UriDeepLinkMatcher برای مسیر تعریف میکنید:
val userMatcher = UriDeepLinkMatcher( DeepLinkUri("www.example.com/user/{id}"), serializer<RouteA>() )
سپس، در onCreate (و onNewIntent) «فعالیت» خود، قصد ورودی را مطابقت میدهید و پشته قبلیها را مقداردهی اولیه میکنید:
val deepLinkMatchers: List<DeepLinkMatcher<*, *>> = listOf( userMatcher, ) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val request = DeepLinkRequest(intent = intent) val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } .maxOrNull() val backStack = when (matchResult) { null -> listOf(HomeKey) is BackStackMatchResult<*, *> -> { @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } else -> listOf(matchResult.key) } // Use backStack with NavDisplay } }
انواع آرگومان سفارشی
در Navigation 2، انواع آرگومانهای سفارشی یا شخص ثالث (مانند
LocalDateTime) را بااستفاده از پیادهسازیهای سفارشی NavType و typeMap مدیریت میکردید.
در Navigation 3، یک DeepLinkSerializer تعریف کنید تا انواع سفارشی یا
شخص ثالث را از پارامترهای URI وازنجیرش کنید. برای جزئیات،
سریالسازی سفارشی با DeepLinkSerializer را ببینید.
برای موارد استفاده پیشرفتهتر، ازجمله پشتههای قبلی مصنوعی و تطبیقدهندههای سفارشی، راهنمای پشتیبانی از پیوندهای عمیق را ببینید.
مرحله ۸: حذف وابستگیهای Navigation 2
همه واردات Navigation 2 و وابستگیهای کتابخانه را بردارید.
خلاصه
تبریک میگوییم! پروژهتان اکنون به Navigation 3 منتقل شده است. اگر شما یا عامل هوش مصنوعیتان هنگام استفاده از این راهنما با مشکلی مواجه شدید، اشکال را در اینجا ثبت کنید.