تشير عملية التنقّل إلى الطريقة التي يتنقّل بها المستخدمون في تطبيقك. ويتفاعل المستخدمون مع عناصر واجهة المستخدم، عادةً من خلال النقر عليها، ويستجيب التطبيق من خلال عرض محتوى جديد. إذا أراد المستخدم الرجوع إلى المحتوى السابق، يمكنه استخدام إيماءة الرجوع أو النقر على زر الرجوع.
إضافة بيانات حالة التنقّل
إحدى الطرق المناسبة لنمذجة هذا السلوك هي استخدام حزمة من المحتوى. عندما ينتقل المستخدم للأمام إلى محتوى جديد، يتم وضعه في أعلى الحزمة. وعندما ينتقل المستخدم للخلف من هذا المحتوى، تتم إزالته من الحزمة ويظهر المحتوى السابق. في ما يتعلّق بالتنقل، يُشار عادةً إلى هذه الحزمة باسم حزمة الرجوع لأنّها تمثّل المحتوى الذي يمكن للمستخدم الرجوع إليه.

إنشاء حزمة الخلفية
في Navigation 3، لا يحتوي سجلّ الرجوع فعليًا على محتوى. بدلاً من ذلك، يحتوي على إشارات إلى المحتوى، تُعرف باسم المفاتيح. يمكن أن تكون المفاتيح من أي نوع، ولكنها عادةً ما تكون فئات بيانات بسيطة وقابلة للتسلسل. يوفّر استخدام المراجع بدلاً من المحتوى المزايا التالية:
- يسهل التنقّل من خلال إضافة مفاتيح إلى حزمة الخلفية.
- وطالما أنّ المفاتيح قابلة للتسلسل، يمكن حفظ سجلّ الرجوع في مساحة تخزين ثابتة، ما يتيح له البقاء على قيد الحياة عند حدوث تغييرات في الإعدادات أو إيقاف العملية. وهذا أمر مهم لأنّ المستخدمين يتوقّعون مغادرة تطبيقك والعودة إليه لاحقًا ومتابعة المحتوى نفسه من حيث توقّفوا. يمكنك الاطّلاع على حفظ سجلّ الرجوع لمزيد من المعلومات.
من المفاهيم الأساسية في واجهة برمجة التطبيقات Navigation 3 أنّك تملك سجلّ الرجوع. المكتبة:
- من المتوقّع أن يكون سجلّ الرجوع عبارة عن
List<T>
مستند إلى حالة اللقطة، حيث يمثّلT
نوع سجلّ الرجوعkeys
. يمكنك استخدامAny
أو تقديم مفاتيح خاصة بك ذات أنواع أكثر صرامة. عندما ترى المصطلحَين "دفع" أو "سحب"، يكون التنفيذ الأساسي هو إضافة عناصر إلى نهاية القائمة أو إزالتها منها. - يراقب سجلّ الرجوع ويعكس حالته في واجهة المستخدم باستخدام
NavDisplay
.
يوضّح المثال التالي كيفية إنشاء مفاتيح وحزمة سابقة، وتعديل الحزمة السابقة استجابةً لأحداث تنقّل المستخدم:
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
حلّ المفاتيح للمحتوى
يتم تصميم المحتوى في Navigation 3 باستخدام NavEntry
، وهو فئة تحتوي على دالة قابلة للإنشاء. يمثّل وجهة، أي جزءًا واحدًا من المحتوى يمكن للمستخدم الانتقال إليه والرجوع منه.
يمكن أن يحتوي NavEntry
أيضًا على بيانات وصفية، أي معلومات عن المحتوى. يمكن أن تقرأ عناصر الحاويات، مثل NavDisplay
، هذه البيانات الوصفية لمساعدتها في تحديد طريقة عرض محتوى NavEntry
. على سبيل المثال، يمكن استخدام بيانات وصفية لتجاوز الرسوم المتحركة التلقائية لعنصر NavEntry
معيّن. NavEntry
metadata
هي خريطة لمفاتيح String
إلى قيم Any
، ما يوفّر تخزينًا متعدد الاستخدامات للبيانات.
لتحويل key
إلى NavEntry
، أنشئ Entry Provider. هذه دالة تقبل key
وتعرض NavEntry
لهذا key
. يتم عادةً تعريفها كمعلَمة lambda عند إنشاء NavDisplay
.
هناك طريقتان لإنشاء Entry Provider، إما عن طريق إنشاء دالة lambda مباشرةً، أو باستخدام لغة النطاق الخاص entryProvider
.
إنشاء دالة Entry Provider مباشرةً
يمكنك عادةً إنشاء دالة Entry Provider باستخدام عبارة when
، مع فرع لكل مفتاح من مفاتيحك.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
استخدام لغة DSL الخاصة بـ entryProvider
يمكن أن تبسّط entryProvider
DSL دالة lambda من خلال تجنُّب الحاجة إلى الاختبار مقابل كل نوع من أنواع المفاتيح، وإنشاء NavEntry
لكل نوع.
استخدِم دالة الإنشاء entryProvider
لهذا الغرض. ويتضمّن أيضًا السلوك التلقائي
للتراجع (عرض خطأ) في حال عدم العثور على المفتاح.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
يُرجى ملاحظة ما يلي من المقتطف:
- تُستخدَم السمة
entry
لتحديدNavEntry
بالنوع المحدّد والمحتوى القابل للإنشاء - تقبل
entry
المَعلمةmetadata
لضبطNavEntry.metadata
عرض سجلّ الرجوع
يمثّل سجلّ الرجوع حالة التنقّل في تطبيقك. وعندما يتغيّر سجلّ الرجوع، يجب أن تعكس واجهة مستخدم التطبيق حالة سجلّ الرجوع الجديدة. في Navigation 3، تراقب
NavDisplay
حزمة الخلفية وتعدّل واجهة المستخدم وفقًا لذلك. أنشئها باستخدام المَعلمات التالية:
- سجلّ الرجوع: يجب أن يكون من النوع
SnapshotStateList<T>
، حيثT
هو نوع مفاتيح سجلّ الرجوع. وهيList
قابلة للملاحظة، لذا تؤدي إلى إعادة إنشاءNavDisplay
عند تغييرها. entryProvider
لتحويل المفاتيح في سجلّ الرجوع إلىNavEntry
عناصر- يمكنك اختياريًا تقديم دالة lambda إلى المَعلمة
onBack
. يتم استدعاء هذا الإجراء عندما ينفّذ المستخدم حدث الرجوع.
يوضّح المثال التالي كيفية إنشاء NavDisplay
.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
تعرض NavDisplay
تلقائيًا NavEntry
في أعلى حزمة الخلفية في تصميم ذي لوحة واحدة. يعرض التسجيل التالي هذا التطبيق قيد التشغيل:

NavDisplay
السلوك التلقائي مع وجهتَينخلاصة ما سبق ذكره
يوضّح الرسم البياني التالي كيفية تدفّق البيانات بين العناصر المختلفة في Navigation 3:

أحداث التنقّل تبدأ التغييرات تتم إضافة المفاتيح أو إزالتها من سجلّ الرجوع استجابةً لتفاعلات المستخدم.
تغيير حالة سجلّ الرجوع يؤدي إلى استرداد المحتوى. تراقب
NavDisplay
(عنصر قابل للإنشاء يعرض الأنشطة السابقة) الأنشطة السابقة. في الإعدادات التلقائية، يعرض التطبيق إدخال سجلّ الرجوع في أعلى الشاشة بتنسيق لوحة واحدة. عندما يتغير المفتاح العلوي في سجلّ الرجوع، يستخدمNavDisplay
هذا المفتاح لطلب المحتوى المقابل من مقدّم بيانات التطبيق.يقدّم موفّر المحتوى المحتوى. موفّر الإدخال هو دالة تحوّل المفتاح إلى
NavEntry
. عند تلقّي مفتاح منNavDisplay
، يقدّم موفّر البياناتNavEntry
المرتبط، والذي يتضمّن المفتاح والمحتوى.يتم عرض المحتوى. يتلقّى
NavDisplay
NavEntry
ويعرض المحتوى.