بخشهای زیر راهبردهای ذخیره کردن پشته قبلیها و ذخیره کردن وضعیت مرتبط با ورودیهای پشته قبلیها را شرح میدهد.
ذخیره کردن پشته قبلیها
اطمینان از اینکه وضعیت پیمایش برنامه شما در رویدادهای مختلف چرخه حیات،
ازجمله تغییرات پیکربندی و مرگ پردازش، پایدار میماند، برای تجربه کاربری خوب
بسیار مهم است. در Navigation 3، پشته قبلیها متعلق به شما است، بنابراین دستورالعملهای سختگیرانهای درباره نحوه ایجاد یا ذخیره آن وجود ندارد. بااینحال، Navigation 3 روشی راحت ارائه میدهد که پشته قبلیها قابلذخیره را دراختیارتان قرار میدهد:
rememberNavBackStack.
استفاده از rememberNavBackStack
تابع ترکیبپذیر rememberNavBackStack برای ایجاد پشته قبلیها طراحی شده است که در تغییرات پیکربندی و مرگ پردازش پایدار میماند.
برای اینکه rememberNavBackStack بهدرستی کار کند، هر کلید در پشته قبلیها
باید از الزامات خاصی پیروی کند:
- پیادهسازی میانای
NavKey: هر کلید در پشته قبلیها باید میانایNavKeyرا پیادهسازی کند. این بهعنوان میانای نشانگر عمل میکند که به کتابخانه علامت میدهد که کلید میتواند ذخیره شود. - حاشیه نویسی
@Serializableرا داشته باشید: علاوهبر پیادهسازیNavKey، کلاسها و اشیاء کلیدی شما باید با حاشیه نویسی@Serializableعلامتگذاری شوند.
قطعه کد زیر پیادهسازی صحیح rememberNavBackStack را نشان میدهد:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
بهخاطر سپردن پشته قبلیها با زیرنوعهای NavKey
تابع ترکیبپذیر rememberNavBackStack یک NavBackStack<NavKey> برمیگرداند.
اگر برنامه شما زیرنوع خودش را از NavKey تعریف میکند که همه کلیدهایش از آن
بهارث میبرند، میتوانید آن تایپ را با پیادهسازی تابع remember سفارشی
بهصورت زیر حفظ کنید:
@Serializable sealed interface MyAppNavKey : NavKey @Serializable data object ScreenA: MyAppNavKey @Serializable data class ScreenB(val id: String): MyAppNavKey @Composable fun rememberMyAppNavBackStack(vararg elements: MyAppNavKey): NavBackStack<MyAppNavKey> { return rememberSerializable(serializer = serializer()) { NavBackStack(*elements) } } @Composable fun MyApp() { // defaultNavBackStack is NavBackStack<NavKey> val defaultNavBackStack = rememberNavBackStack(ScreenA) // myAppNavBackStack is NavBackStack<MyAppNavKey> val myAppNavBackStack = rememberMyAppNavBackStack(ScreenA) }
برای مثالهای بیشتر (ازجمله نحوه مدیریت چندریختی باز)، به
NavBackStackSamples مراجعه کنید.
جایگزین: ذخیره در ViewModel
رویکرد دیگر برای مدیریت پشته قبلیها ذخیره کردن آن در ViewModel است.
برای پایداری درصورت مرگ پردازش هنگام استفاده از ViewModel یا هر فضای ذخیرهسازی سفارشی دیگر، باید:
- مطمئن شوید کلیدهایتان قابلسریالسازی باشند: درست مانند
rememberNavBackStack، کلیدهای پیمایش شما باید قابلسریالسازی باشند. - مدیریت دستی سریالسازی و غیرسریالسازی: شما مسئول هستید که
نمایش سریالسازیشده هر کلید را بهصورت دستی در فضای ذخیرهسازی پایدار (مثلاً
SharedPreferences، پایگاه داده، یا فایل) ذخیره کنید و آن را از آنجا غیرسریالسازی کنید، زمانی که برنامهتان به پسزمینه میرود یا بازیابی میشود.
درحال محدود کردن ViewModel نمونه به NavEntry شیء
از ViewModels برای حفظ حالت مربوط به میانای کاربر در تغییرات پیکربندی،
مانند چرخش صفحهنمایش، استفاده میشود. بهطور پیشفرض، ViewModels به نزدیکترین
ViewModelStoreOwner محدود میشود که معمولاً Activity یا Fragment شما است.
بااینحال، ممکن است بخواهید بهجای کل Activity، یک ViewModel را به یک NavEntry خاص (یعنی یک صفحه یا مقصد خاص) در پشته قبلیها محدود کنید. این کار تضمین میکند که وضعیت ViewModel فقط زمانی حفظ میشود که
NavEntry خاص بخشی از پشته قبلیها باشد و وقتی NavEntry
پاپ شود، پاک میشود.
کتابخانه برافزای androidx.lifecycle:lifecycle-viewmodel-navigation3
NavEntryDecorator را ارائه میدهد که این کار را تسهیل میکند. این دکوراتور یک
ViewModelStoreOwner برای هر NavEntry ارائه میدهد. وقتی ViewModel را در محتوای
NavEntry ایجاد میکنید (مثلاً بااستفاده از viewModel() در Compose)، بهطور خودکار
به کلید آن NavEntry خاص در پشته قبلیها محدود میشود. این یعنی
ViewModel وقتی ایجاد میشود که NavEntry به پشته قبلیها اضافه شود، و
وقتی برداشته شود پاک میشود.
برای استفاده از NavEntryDecorator برای محدود کردن ViewModel به NavEntry، این مراحل را دنبال کنید:
- وابستگی
androidx.lifecycle:lifecycle-viewmodel-navigation3را به فایلapp/build.gradle.ktsاضافه کنید. rememberSaveableStateHolderNavEntryDecorator()پیشفرض را هنگام ساختنNavDisplayبه فهرستentryDecoratorsاضافه کنید.rememberViewModelStoreNavEntryDecorator()را به فهرستentryDecoratorsاضافه کن.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSaveableStateHolderNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )