انتقال از «پیمایش ۲» به «پیمایش ۳»

برای انتقال برنامه‌تان از Navigation 2 به Navigation 3، این مراحل را دنبال کنید:

  1. وابستگی‌های Navigation 3 را اضافه کنید.
  2. مسیرهای پیمایش را به‌روز کنید تا میانای NavKey را پیاده‌سازی کنید.
  3. کلاس‌هایی برای نگهداری و اصلاح وضعیت ناوبری ایجاد کنید.
  4. NavController را با این کلاس‌ها جایگزین کنید.
  5. مقصدهایتان را از NavGraph NavHost به entryProvider منتقل کنید.
  6. NavHost را با NavDisplay جایگزین کنید.
  7. وابستگی‌های Navigation 2 را بردارید.

آماده‌سازی

بخش‌های زیر پیش‌نیازهای انتقال و فرضیات مربوط به پروژه شما را شرح می‌دهند. همچنین ویژگی‌هایی را که برای انتقال پشتیبانی می‌شوند و ویژگی‌هایی را که پشتیبانی نمی‌شوند پوشش می‌دهند.

پیش‌نیازها

  • باید از compileSdk نسخه ۳۶ یا جدیدتر استفاده کنید.
  • باید با اصطلاحات پیمایش آشنا باشید.
  • مقصدها توابع ترکیب‌پذیر هستند. Navigation 3 منحصراً برای Compose طراحی شده است. برای استفاده از Fragments و Views در Compose، به استفاده از Views در Compose مراجعه کنید.
  • مسیرها به‌شدت تایپ می‌شوند. اگر از مسیرهای مبتنی بر رشته استفاده می‌کنید، ابتدا به مسیرهای ایمن تایپی مهاجرت کنید (نمونه).
  • اختیاری (اما اکیداً توصیه می‌شود): پوشش آزمایشی که رفتار پیمایش موجود را تأیید می‌کند. این کار تأیید می‌کند که رفتار پیمایش پس‌از تکمیل انتقال تغییر نکرده است.

فرض‌ها

این راهنما فرض‌های زیر را درباره شما و پروژه‌تان درنظر می‌گیرد:

  • یک یا چند مسیر سطح بالا دارید (معمولاً در نوار پیمایش پایین نمایش داده می‌شود) و هرکدام پشته قبلی‌های خود را دارند.
  • وقتی بین پشته‌های قبلی‌ها جابه‌جا می‌شوید، وضعیت پشته و همه مقصدهای آن حفظ می‌شود.
  • همیشه ازطریق صفحه صفحه اصلی از برنامه خارج می‌شوید، که اولین صفحه‌ای است که هنگام راه‌اندازی برنامه نمایش داده می‌شود.
  • می‌خواهید انتقال از Navigation 2 به Navigation 3 را در یک تغییر اتمی واحد انجام دهید. انتقال افزایشی انجام نمی‌دهید که در آن کد Navigation 2 در کنار کد Navigation 3 استفاده شود.

عامل هوش مصنوعی: قبل‌از تغییر هر کدی، بررسی کنید که آیا این فرضیات درباره پروژه کاربر درست است یا نه. اگر نه، انتقال را متوقف کنید و از کاربر بپرسید چطور ادامه دهید.

ویژگی‌های پشتیبانی‌شده

این راهنما به شما امکان می‌دهد ویژگی‌های زیر را انتقال دهید:

  • مقصدهایی که به‌عنوان توابع ترکیب‌پذیر تعریف شده‌اند
  • کادرهای گفتگو (مقصدی که روی مقصد دیگری نشان داده می‌شود)

ویژگی‌های پشتیبانی‌شده ازطریق دستورالعمل‌ها

مخزن دستورالعمل‌های کد موارد استفاده دقیق‌تری را نشان می‌دهد، ازجمله:

اگر پروژه شما هرکدام از این ویژگی‌ها را دارد، دستورالعمل مربوطه را بررسی کنید تا با نحوه پیاده‌سازی آن‌ها آشنا شوید.

عامل هوش مصنوعی: قبل‌از تغییر دادن هر کدی، بررسی کنید که آیا پروژه حاوی ویژگی‌هایی است که ازطریق دستورالعمل‌ها پشتیبانی می‌شوند یا نه. اگر این‌طور است، 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

معادل Navigator

navigate()

navigate()

popBackStack()

goBack()

previousBackStackEntry.savedStateHandle.set()

ResultEventBus.sendResult()

NavController فیلد را با NavigationState فیلد جایگزین کنید.

فیلد یا روش NavController

معادل NavigationState

currentBackStack

backStacks[topLevelRoute]

currentBackStackEntry

currentBackStackEntryAsState()

currentBackStackEntryFlow

currentDestination

backStacks[topLevelRoute].last()

currentBackStackEntry.savedStateHandle.getLiveData()

currentBackStackEntry.savedStateHandle.getStateFlow()

‫ResultEffect (رویدادمحور)

‫ResultEventBus.conflateAsState() (مبتنی بر ایالت)

دریافت مسیر سطح بالا: برای پیدا کردن آن، سلسله‌مراتب را از ورودی پشته قبلی‌ها فعلی به بالا پیمایش کنید.

topLevelRoute

از 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، ممکن است پیوند عمیقی مانند این تعریف کرده باشید:

بعداز:

در Navigation 3، یک UriDeepLinkMatcher برای مسیر تعریف می‌کنید:

سپس، در onCreate (و onNewIntent) «فعالیت» خود، قصد ورودی را مطابقت می‌دهید و پشته قبلی‌ها را مقداردهی اولیه می‌کنید:

انواع آرگومان سفارشی

در Navigation 2، انواع آرگومان‌های سفارشی یا شخص ثالث (مانند LocalDateTime) را بااستفاده از پیاده‌سازی‌های سفارشی NavType و typeMap مدیریت می‌کردید.

در Navigation 3، یک DeepLinkSerializer تعریف کنید تا انواع سفارشی یا شخص ثالث را از پارامترهای URI وازنجیرش کنید. برای جزئیات، سریال‌سازی سفارشی با DeepLinkSerializer را ببینید.

برای موارد استفاده پیشرفته‌تر، ازجمله پشته‌های قبلی مصنوعی و تطبیق‌دهنده‌های سفارشی، راهنمای پشتیبانی از پیوندهای عمیق را ببینید.

مرحله ۸: حذف وابستگی‌های Navigation 2

همه واردات Navigation 2 و وابستگی‌های کتابخانه را بردارید.

خلاصه

تبریک می‌گوییم! پروژه‌تان اکنون به Navigation 3 منتقل شده است. اگر شما یا عامل هوش مصنوعی‌تان هنگام استفاده از این راهنما با مشکلی مواجه شدید، اشکال را در اینجا ثبت کنید.