حفظ حالة التنقّل وإدارتها

توضّح الأقسام التالية استراتيجيات لحفظ سجلّ الرجوع وتخزين الحالة المرتبطة بالإدخالات في سجلّ الرجوع.

حفظ سجلّ الرجوع

يُعدّ ضمان استمرار حالة التنقّل في تطبيقك خلال أحداث مراحل النشاط المختلفة، بما في ذلك تغييرات الإعدادات وإيقاف العملية، أمرًا بالغ الأهمية لتقديم تجربة جيدة للمستخدم. في Navigation 3، يمكنك التحكّم في سجلّ الرجوع، لذا لا توجد إرشادات صارمة حول كيفية إنشائه أو حفظه. ومع ذلك، يوفّر الإصدار 3 من Navigation طريقة ملائمة تتيح لك الحصول على سجلّ رجوع يمكن حفظه: 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() في Compose)، يتم تلقائيًا تحديد نطاق ViewModel ليطابق مفتاح NavEntry المحدّد في سجلّ الرجوع. وهذا يعني أنّه يتم إنشاء ViewModel عند إضافة NavEntry إلى سجلّ الرجوع، ويتم محوه عند إزالته.

لاستخدام NavEntryDecorator لتحديد نطاق ViewModels إلى NavEntrys، اتّبِع الخطوات التالية:

  1. أضِف تبعية androidx.lifecycle:lifecycle-viewmodel-navigation3 إلى ملف app/build.gradle.kts.
  2. أضِف rememberSaveableStateHolderNavEntryDecorator() إلى قائمة entryDecorators عند إنشاء NavDisplay.
  3. أضِف أدوات تزيين أخرى إلى 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 { },
)