ناوبری و پشته پشته

NavController یک "پشته پشتی" را نگه می دارد که حاوی مقاصدی است که کاربر بازدید کرده است. هنگامی که کاربر به صفحه نمایش در سراسر برنامه شما پیمایش می کند، NavController مقصدهایی را به پشته و از پشته اضافه می کند و حذف می کند.

در پشته بودن، پشته پشته یک ساختار داده "آخرین ورود، اولین خروج" است. بنابراین NavController آیتم‌ها را به بالای پشته هل می‌دهد و از آن‌ها بیرون می‌آورد.

رفتار اساسی

اینها حقایق اصلی هستند که باید در مورد رفتار پشته پشتی در نظر بگیرید:

  • مقصد اول: هنگامی که کاربر برنامه را باز می کند، NavController اولین مقصد را به بالای پشته پشتی فشار می دهد.
  • فشار دادن به پشته: هر فراخوان NavController.navigate() مقصد داده شده را به بالای پشته هل می دهد.
  • مقصد بالای صفحه: ضربه زدن به بالا یا برگشت به ترتیب متدهای NavController.navigateUp() و NavController.popBackStack() را فراخوانی می کند. آنها مقصد بالا را از پشته بیرون می آورند. برای اطلاعات بیشتر در مورد تفاوت بین بالا و عقب به صفحه اصول پیمایش مراجعه کنید.

به عقب برگرد

متد NavController.popBackStack() سعی می کند مقصد فعلی را از پشته خارج کند و به مقصد قبلی حرکت کند. این به طور موثر کاربر را یک قدم در تاریخچه ناوبری خود به عقب می برد. یک Boolean برمی گرداند که نشان می دهد آیا با موفقیت به مقصد بازگشته است یا خیر.

به یک مقصد خاص برگردید

همچنین می توانید از popBackStack() برای حرکت به یک مقصد خاص استفاده کنید. برای انجام این کار، از یکی از اضافه بارهای آن استفاده کنید. چندین مورد وجود دارد که به شما امکان می دهد در یک شناسه عبور کنید، مانند id عدد صحیح یا route رشته. این اضافه بارها کاربر را به مقصد مرتبط با شناسه داده شده می برد. به طور بحرانی، آنها همه چیز را در پشته بالای آن مقصد قرار می دهند.

این اضافه بارها یک بولی inclusive نیز می گیرند. تعیین می کند که آیا NavController باید پس از پیمایش به مقصد، مقصد مشخص شده را نیز از پشته خارج کند.

به عنوان مثال این قطعه کوتاه را در نظر بگیرید:

navController.popBackStack(R.id.destinationId, true)

در اینجا NavController با destinationId عدد صحیح DestinId به مقصد بازمی گردد. از آنجایی که مقدار آرگومان inclusive true است، NavController نیز مقصد داده شده را از پشته باز می کند.

یک پاپ بک شکست خورده را مدیریت کنید

وقتی popBackStack() false را برمی گرداند، فراخوانی بعدی به NavController.getCurrentDestination() null برمی گرداند. این بدان معنی است که برنامه آخرین مقصد را از پشته خارج کرده است. در این حالت کاربر فقط یک صفحه خالی را می بیند.

این می تواند در موارد زیر رخ دهد:

  • popBackStack() چیزی از پشته بیرون نیاورد.
  • popBackStack() مقصدی را از پشته بیرون آورد و پشته اکنون خالی است.

برای حل این مشکل، سپس باید به یک مقصد جدید بروید یا برای پایان دادن به فعالیت خود finish() فراخوانی کنید. قطعه زیر این را نشان می دهد:

کاتلین

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish()
}

جاوا

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish();
}

پاپ تا به یک مقصد

برای حذف مقصدها از پشته پشته هنگام پیمایش از یک مقصد به مقصد دیگر، یک آرگومان popUpTo() به فراخوانی تابع navigate() مرتبط اضافه کنید. popUpTo() به کتابخانه Navigation دستور می دهد تا برخی از مقصدها را به عنوان بخشی از فراخوانی navigate() از پشته پشتی حذف کند. مقدار پارامتر، شناسه مقصد در پشته پشتی است. شناسه می تواند یک id عدد صحیح یا route رشته باشد.

شما می توانید یک آرگومان برای پارامتر inclusive با مقدار true اضافه کنید تا نشان دهد که مقصدی که در popUpTo() مشخص کرده اید نیز باید پشته پشتی را باز کند.

برای پیاده‌سازی برنامه‌ای، popUpTo() به navigate() به عنوان بخشی از NavOptions با مجموعه inclusive true ارسال کنید. این هم در Compose و هم در Views کار می کند.

ذخیره حالت هنگام ظاهر شدن

هنگامی که popUpTo برای پیمایش به یک مقصد استفاده می‌کنید، می‌توانید به‌صورت اختیاری پشته پشتی را ذخیره کنید و وضعیت‌های همه مقصدها از پشته خارج می‌شوند. پس از آن می‌توانید پشته و مقصدها را هنگام حرکت به آن مقصد در زمان دیگری بازیابی کنید. این به شما امکان می دهد وضعیت را برای یک مقصد مشخص حفظ کنید و پشته های متعددی داشته باشید.

برای انجام این کار به صورت برنامه نویسی، هنگام افزودن popUpTo به گزینه های پیمایش خود، saveState = true مشخص کنید.

همچنین می توانید restoreState = true در گزینه های پیمایش خود تعیین کنید تا پشته پشته و وضعیت مرتبط با مقصد به طور خودکار بازیابی شود.

به عنوان مثال:

navController.navigate(
    route = route,
    navOptions =  navOptions {
        popUpTo<A>{ saveState = true }
        restoreState = true
    }
)

برای فعال کردن حالت ذخیره و بازیابی در XML، popUpToSaveState به ترتیب به عنوان true و restoreState به عنوان true در action مرتبط تعریف کنید.

مثال XML

در اینجا یک مثال از popUpTo در XML، با استفاده از یک عمل آورده شده است:

<action
  android:id="@+id/action_a_to_b"
  app:destination="@id/b"
  app:popUpTo="@+id/a"
  app:popUpToInclusive="true"
  app:restoreState=”true”
  app:popUpToSaveState="true"/>

مثال بنویسید

مثال زیر یک مثال کامل از همین موضوع در Compose است:

@Composable
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: Any = A
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable<A> {
            DestinationA(
                onNavigateToB = {
                // Pop everything up to, and including, the A destination off
                // the back stack, saving the back stack and the state of its
                // destinations.
                // Then restore any previous back stack state associated with
                // the B destination.
                // Finally navigate to the B destination.
                    navController.navigate(route = B) {
                        popUpTo<A> {
                            inclusive = true
                            saveState = true
                        }
                        restoreState = true
                    }
                },
            )
        }
        composable<B> { DestinationB(/* ... */) }
    }
}

@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
    Button(onClick = onNavigateToB) {
        Text("Go to A")
    }
}

به طور دقیق تر، می توانید نحوه فراخوانی NavController.navigate() به روش های زیر تغییر دهید:

// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a")
}

// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a") { inclusive = true }
}

// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
    launchSingleTop = true
}

برای اطلاعات کلی در مورد انتقال گزینه‌ها به NavController.navigate() ، به راهنمای Navigate with options مراجعه کنید.

پاپ با استفاده از اقدامات

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

خواندن اضافی

برای اطلاعات بیشتر صفحات زیر را مطالعه کنید:

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