حفظ حالة التنقّل وإدارتها
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
توضِّح الأقسام التالية استراتيجيات حفظ الحزمة الخلفية و
تخزين الحالة المرتبطة بالإدخالات في الحزمة الخلفية.
حفظ الحزمة الخلفية
إنّ ضمان استمرار حالة التنقّل في تطبيقك على مستوى أحداث دورة الحياة المختلفة،
بما في ذلك تغييرات الإعدادات وانتهاء العملية، هو أمر مهم لتوفير تجربة
مستخدم جيدة. في Navigation 3، تكون حزمة التطبيقات التي سبق لك فتحها ملكًا لك، لذا لا تتوفّر إرشادات
صارمة حول كيفية إنشائها أو حفظها. ومع ذلك، يوفّر التنقّل 3
طريقة سهلة تمنحك حزمة "الرجوع" التي يمكن حفظها:
rememberNavBackStack
.
استخدام rememberNavBackStack
تم تصميم الدالة القابلة للتجميع rememberNavBackStack
لإنشاء ملف rememberNavBackStack
احتياطي يبقى محفوظًا على الرغم من تغييرات الإعدادات وإيقاف العملية.
لكي يعمل rememberNavBackStack
بشكل صحيح، يجب أن يلتزم كل مفتاح في الحزمة الخلفية
بمتطلبات معيّنة:
- تنفيذ واجهة
NavKey
: يجب أن ينفذ كل مفتاح في الحزمة الخلفية
واجهة NavKey
. ويعمل هذا العنصر كواجهة علامة تشير إلى
المكتبة بأنّه يمكن حفظ المفتاح.
- توفُّر التعليق التوضيحي
@Serializable
: بالإضافة إلى تنفيذ NavKey
،
يجب وضع علامة على الفئات والكائنات الرئيسية باستخدام التعليق التوضيحي @Serializable
.
يعرض المقتطف التالي تنفيذًا صحيحًا لـ rememberNavBackStack
:
@Serializable
data object Home : NavKey
@Composable
fun NavBackStack() {
val backStack = rememberNavBackStack(Home)
}
البديل: التخزين في ViewModel
هناك طريقة أخرى لإدارة الحزمة الخلفية وهي تخزينها في ViewModel
.
للحفاظ على البيانات بعد إيقاف العملية نهائيًا عند استخدام ViewModel
أو أي ملف تخزين
مخصّص آخر، عليك إجراء ما يلي:
- التأكّد من إمكانية تسلسل المفاتيح: تمامًا كما هو الحال مع
rememberNavBackStack
،
يجب أن تكون مفاتيح التنقّل قابلة للتسلسل.
- معالجة التسلسل وإزالة التسلسل يدويًا: تكون أنت المسؤول عن
حفظ التمثيل التسلسلي لكل مفتاح يدويًا في مساحة التخزين الثابتة
وإزالة تسلسله منها (مثل
SharedPreferences
أو قاعدة بيانات أو ملف) عند نقل تطبيقك إلى الخلفية أو عند
استعادته.
تحديد نطاق ViewModel
إلى NavEntry
ViewModels
تُستخدَم للاحتفاظ بالحالة المتعلّقة بواجهة المستخدم على الرغم من تغييرات الضبط،
مثل عمليات تدوير الشاشة. تكون ViewModels
مقيّدة تلقائيًا بأقرب
ViewModelStoreOwner
، والذي يكون عادةً Activity
أو Fragment
.
ومع ذلك، قد تحتاج إلى حصر ViewModel
في NavEntry
معيّن (أي
شاشة أو وجهة معيّنة) في الحزمة الخلفية، بدلاً من
Activity
بأكمله. يضمن ذلك الاحتفاظ بحالة ViewModel
فقط عندما يكون
NavEntry
المحدّد جزءًا من الحزمة الخلفية، ويتم محوه عند التمرير سريعًا
NavEntry
.
توفّر مكتبة الإضافات androidx.lifecycle:lifecycle-viewmodel-navigation3
NavEntryDecorator
يسهّل ذلك. يقدّم هذا العنصر الزخرفي ViewModelStoreOwner
لكل NavEntry
. عند إنشاء ViewModel
داخل محتوى
NavEntry
(مثل استخدام viewModel()
في ميزة "الإنشاء")، يتم
حصره تلقائيًا بمفتاح NavEntry
المحدّد هذا في الحزمة الخلفية. وهذا يعني أنّه يتم إنشاء
ViewModel
عند إضافة NavEntry
إلى الحزمة الخلفية، ويتم
محو القيمة عند إزالتها.
لاستخدام NavEntryDecorator
لتحديد نطاق ViewModel
إلى NavEntry
، اتّبِع الخطوات التالية:
- أضِف التبعية
androidx.lifecycle:lifecycle-viewmodel-navigation3
إلىملف app/build.gradle.kts
.
- أضِف
rememberSavedStateNavEntryDecorator()
إلى قائمة
entryDecorators
عند إنشاء NavDisplay
.
- أضِف أدوات تزيين أخرى إلى
NavDisplay
.
NavDisplay(
entryDecorators = listOf(
// Add the default decorators for managing scenes and saving state
rememberSceneSetupNavEntryDecorator(),
rememberSavedStateNavEntryDecorator(),
// Then add the view model store decorator
rememberViewModelStoreNavEntryDecorator()
),
backStack = backStack,
entryProvider = entryProvider { },
)
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["# Save and manage navigation state\n\nThe following sections describe strategies for saving your back stack and\nstoring state associated with entries on your back stack.\n\nSave your back stack\n--------------------\n\nEnsuring your app's navigation state persists across various lifecycle events,\nincluding configuration changes and process death, is crucial for a good user\nexperience. In Navigation 3, you own your back stack, so there aren't strict\nguidelines on how you should create or save it. However, Navigation 3 does offer\na convenience method that provides you with a saveable back stack:\n[`rememberNavBackStack`](/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberNavBackStack(kotlin.Array)).\n\n### Use `rememberNavBackStack`\n\nThe `rememberNavBackStack` composable function is designed to create a back\nstack that persists across configuration changes and process death.\n\nFor `rememberNavBackStack` to function correctly, each key in your back stack\nmust adhere to specific requirements:\n\n- **Implement `NavKey` interface** : Every key in the back stack must implement the [`NavKey`](/reference/kotlin/androidx/navigation3/runtime/NavKey) interface. This acts as a marker interface that signals to the library that the key can be saved.\n- **Have the `@Serializable` annotation** : In addition to implementing `NavKey`, your key classes and objects must be marked with the `@Serializable` annotation.\n\nThe following snippet shows a correct implementation of `rememberNavBackStack`:\n\n\n```kotlin\n@Serializable\ndata object Home : NavKey\n\n@Composable\nfun NavBackStack() {\n val backStack = rememberNavBackStack(Home)\n}https://github.com/android/snippets/blob/26d364466ee1c03d658ba2f0905f7cc1a97afefa/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/savingstate/SavingStateSnippets.kt#L30-L36\n```\n\n\u003cbr /\u003e\n\n### Alternative: Storing in a `ViewModel`\n\nAnother approach to managing your back stack is to store it in a `ViewModel`.\nFor persistence through process death when using a `ViewModel` or any other\ncustom storage, you need to:\n\n- **Ensure your keys are serializable** : Just like with `rememberNavBackStack`, your navigation keys must be serializable.\n- **Handle serialization and deserialization manually** : You're responsible for manually saving the serialized representation of each key to, and deserializing it from, persistent storage (e.g., `SharedPreferences`, a database, or a file) when your app is going into the background or being restored.\n\nScoping `ViewModel`s to `NavEntry`s\n-----------------------------------\n\n`ViewModels` are used to retain UI-related state across configuration changes,\nsuch as screen rotations. By default, `ViewModels` are scoped to the nearest\n`ViewModelStoreOwner`, which is typically your `Activity` or `Fragment`.\n\nHowever, you might want to scope a `ViewModel` to a specific `NavEntry` (i.e., a\nspecific screen or destination) on the back stack, rather than the entire\n`Activity`. This ensures that the `ViewModel`'s state is retained only while\nthat particular `NavEntry` is part of the back stack, and is cleared when the\n`NavEntry` is popped.\n\nThe `androidx.lifecycle:lifecycle-viewmodel-navigation3` add-on library provides\na `NavEntryDecorator` that facilitates this. This decorator provides a\n`ViewModelStoreOwner` for each `NavEntry`. When you create a `ViewModel` inside a\n`NavEntry`'s content (e.g., using `viewModel()` in Compose), it is automatically\nscoped to that specific `NavEntry`'s key on the back stack. This means the\n`ViewModel` is created when the `NavEntry` is added to the back stack, and\ncleared when it's removed.\n\nTo use `NavEntryDecorator` for scoping `ViewModel`s to `NavEntry`s, follow these\nsteps:\n\n1. Add the `androidx.lifecycle:lifecycle-viewmodel-navigation3` dependency to your `app/build.gradle.kts` file.\n2. Add [`rememberSavedStateNavEntryDecorator()`](/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberSavedStateNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder)) to the list of `entryDecorators` when constructing a `NavDisplay`.\n3. Add other decorators into your `NavDisplay`.\n\n\n```kotlin\nNavDisplay(\n entryDecorators = listOf(\n // Add the default decorators for managing scenes and saving state\n rememberSceneSetupNavEntryDecorator(),\n rememberSavedStateNavEntryDecorator(),\n // Then add the view model store decorator\n rememberViewModelStoreNavEntryDecorator()\n ),\n backStack = backStack,\n entryProvider = entryProvider { },\n)https://github.com/android/snippets/blob/26d364466ee1c03d658ba2f0905f7cc1a97afefa/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/savingstate/SavingStateSnippets.kt#L45-L55\n```\n\n\u003cbr /\u003e"]]