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

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

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

آماده‌سازی

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

پیش‌نیازها

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

فرض‌ها

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

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

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

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

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

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

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

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

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

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

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

این راهنمای انتقال و دستورالعمل‌های کد هنوز از ویژگی‌های زیر پشتیبانی نمی‌کنند. این بدان معنا نیست که نمی‌توانید آن‌ها را بااستفاده از «پیمایش ۳» پیاده‌سازی کنید؛ فقط در اینجا پوشش داده نشده‌اند.

  • بیش‌از یک سطح پیمایش تودرتو
  • مقاصد هم‌رسانی‌شده: صفحه‌هایی که می‌توانند بین پشته‌های برگشت مختلف جابه‌جا شوند
  • انواع مقصد سفارشی

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

مرحله ۱: افزودن ۳ وابستگی «ناوبری»

از صفحه شروع کار برای افزودن وابستگی‌های «پیمایش ۳» به پروژه‌تان استفاده کنید. وابستگی‌های اصلی برای کپی کردن دراختیارتان قرار داده شده است.

lib.versions.toml

[versions]
nav3Core = "1.2.0"

# 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، ازجمله همه وارد کردن‌ها، را برداشته‌اید.

مرحله ۴.۱ انتقال منطق آگاه از چرخه حیات

در «پیمایش ۲»، NavBackStackEntry LifecycleOwner را پیاده‌سازی می‌کند و به شما امکان می‌دهد بااستفاده از navController.currentBackStackEntry به رویدادهای چرخه حیات گوش دهید یا جریان‌ها را به‌شیوه‌ای آگاه از چرخه حیات جمع‌آوری کنید.

در «ناوبری ۳»، NavDisplay ازطریق LocalLifecycleOwner.current به محتوای ترکیبی هر مقصد، LifecycleOwner با حوزه ورودی ارائه می‌دهد. برای اطلاعات بیشتر، چرخه حیات مقصد را ببینید.

با ارجاع دادن به 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()

مرحله ۴.۲ انتقال نتایج

در «پیمایش ۲»، مقصدها بااستفاده از SavedStateHandle در NavBackStackEntry نتایج را به مقصدهای قبلی برمی‌گرداندند. چون SavedStateHandle با وضعیت نمونه ذخیره‌شده پشتیبانی می‌شود، داده‌های برگشتی به‌طور خودکار از مرگ فرایند جان سالم به‌در برد.

پیش‌از:

// 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

در «پیمایش ۲»، بااستفاده از NavGraphBuilder DSL، معمولاً در لامبدای انتهایی NavHost، مقصدها را تعریف می‌کنید. در اینجا معمولاً از تابع‌های افزونه همان‌طور که در کد پیمایش خود را کپسوله کنید توضیح داده شده است استفاده می‌شود.

در «ناوبری ۳»، مقصدهای خود را بااستفاده از 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<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()) }
)

مرحله ۷: انتقال پیوندهای عمیق

در «پیمایش ۲»، پیوندهای عمیق مستقیماً در نمودار پیمایش بااستفاده از پارامتر deepLinks مقصدها تعریف شده است.

در «پیمایش ۳»، پیوندهای عمیق به‌طور مستقل از رابط کاربری پیمایش مدیریت می‌شوند. DeepLinkMatcher را تعریف می‌کنید و درخواست‌های ورودی را در «فعالیت» خودتان مطابقت می‌دهید تا پشته برگشت اولیه را بسازید.

پیش‌از:

در «پیمایش ۲»، ممکن است پیوند عمیقی را به‌این‌صورت تعریف کرده باشید:

پس‌از:

در «پیمایش ۳»، UriDeepLinkMatcher را برای مسیر تعریف می‌کنید:

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

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

در «پیمایش ۲»، انواع آرگومان سفارشی یا طرف سوم (مثل LocalDateTime) را بااستفاده از پیاده‌سازی‌های سفارشی NavType و typeMap مدیریت می‌کردید.

در «پیمایش ۳»، DeepLinkSerializer را برای سریال‌سازی انواع سفارشی یا طرف سوم از پارامترهای نشانی وب تعریف کنید. برای جزئیات بیشتر، سریال‌سازی سفارشی با DeepLinkSerializer را ببینید.

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

مرحله ۸: برداشتن وابستگی‌های «ناوبری ۲»

همه واردات «پیمایش ۲» و وابستگی‌های کتابخانه را بردارید.

خلاصه

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