يحتوي NavController على "سجلّ رجوع" يتضمّن الوجهات التي زارها المستخدم. أثناء تنقّل المستخدم بين الشاشات في تطبيقك، يضيف
NavController وجهات إلى حزمة الخلفية ويزيل منها.
وبما أنّها مكدّس، فإنّ حزمة السجلّ الخلفي هي هيكل بيانات "آخر ما يتم إدخاله هو أول ما يتم إخراجه". وبالتالي، يضيف NavController العناصر إلى أعلى الحزمة ويزيلها منها.
أسلوب الأداء الأساسي
في ما يلي الحقائق الأساسية التي يجب مراعاتها بشأن سلوك حزمة الخلف:
- الوجهة الأولى: عندما يفتح المستخدم التطبيق، يضع
NavControllerالوجهة الأولى في أعلى حزمة الخلفية. - إضافة عنصر إلى الحزمة: تؤدي كل عملية استدعاء
NavController.navigate()إلى إضافة الوجهة المحدّدة إلى أعلى الحزمة. - الوجهة العلوية الظاهرة: يؤدي النقر على أعلى أو رجوع إلى استدعاء الطريقتَين
NavController.navigateUp()وNavController.popBackStack()على التوالي. يتم إزالة الوجهة العلوية من الحزمة. يمكنك الاطّلاع على صفحة مبادئ التنقّل للحصول على مزيد من المعلومات حول الفرق بين أعلى ورجوع.
الرجوع إلى الخلف
تحاول الطريقة NavController.popBackStack() إزالة الوجهة الحالية من الخلفية والانتقال إلى الوجهة السابقة. يؤدي ذلك إلى إعادة المستخدم خطوة واحدة إلى الوراء في سجلّ التنقّل. تعرض هذه الدالة قيمة منطقية تشير إلى ما إذا كان قد تم الرجوع إلى الوجهة بنجاح.
العودة إلى وجهة معيّنة
يمكنك أيضًا استخدام popBackStack() للانتقال إلى وجهة معيّنة. لإجراء ذلك، استخدِم أحد التحميلات الزائدة. هناك عدة طرق تتيح لك إدخال معرّف، مثل عدد صحيح id أو سلسلة route. تنقل عمليات التحميل الزائد هذه المستخدم إلى الوجهة المرتبطة بالمعرّف المحدّد. والأهم من ذلك،
أنّها تزيل كل العناصر من الحزمة فوق تلك الوجهة.
تتضمّن هذه الأحمال الزائدة أيضًا قيمة منطقية inclusive. تحدّد هذه السمة ما إذا كان يجب أن يؤدي NavController أيضًا إلى إزالة الوجهة المحدّدة من حزمة الأنشطة السابقة بعد الانتقال إليها.
إليك مقتطفًا موجزًا كمثال:
navController.popBackStack(R.id.destinationId, true)
في هذه الحالة، يعود NavController إلى الوجهة مع المعرّف العددي destinationId. بما أنّ قيمة الوسيطة inclusive هي true، فإنّ NavController ستزيل أيضًا الوجهة المحدّدة من سجلّ الرجوع.
التعامل مع ظهور نافذة منبثقة غير متوقّعة
عندما تعرض الدالة popBackStack() القيمة false، ستعرض الدالة NavController.getCurrentDestination() القيمة null في مكالمة لاحقة. وهذا يعني أنّ التطبيق قد أزال الوجهة الأخيرة من حزمة السجلّ الخلفي. في هذه الحالة، لن يرى المستخدم سوى شاشة فارغة.
يمكن أن يحدث ذلك في الحالات التالية:
- لم يزِل
popBackStack()أي عناصر من الحزمة. - نفّذت الدالة
popBackStack()عملية إزالة وجهة من الأنشطة السابقة، وأصبحت الأنشطة السابقة فارغة الآن.
لحلّ هذه المشكلة، عليك الانتقال إلى وجهة جديدة أو الاتصال بـ finish()
في نشاطك لإنهاء النشاط. يوضّح المقتطف التالي ذلك:
kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
الوصول إلى وجهة معيّنة
لإزالة الوجهات من الأنشطة السابقة عند التنقّل من وجهة إلى أخرى، أضِف وسيطة popUpTo() إلى استدعاء الدالة navigate() المرتبط. يطلب popUpTo() من مكتبة التنقّل إزالة بعض الوجهات
من حزمة الأنشطة السابقة كجزء من طلب navigate(). قيمة المَعلمة هي معرّف الوجهة في سجلّ الأنشطة السابقة. يمكن أن يكون المعرّف عددًا صحيحًا id أو سلسلة route.
يمكنك تضمين وسيطة للمَعلمة inclusive بقيمة true للإشارة إلى أنّ الوجهة التي حدّدتها في popUpTo() يجب أيضًا إزالتها من حزمة الأنشطة السابقة.
لتنفيذ ذلك برمجيًا، مرِّر popUpTo() إلى navigate() كجزء من
NavOptions مع ضبط inclusive على true. يمكن استخدام هذه السمة في كلّ من Compose وViews.
حفظ الحالة عند ظهور النافذة المنبثقة
عند استخدام popUpTo للتنقّل إلى وجهة، يمكنك اختياريًا حفظ الأنشطة السابقة وحالات جميع الوجهات التي تمت إزالتها من الأنشطة السابقة. يمكنك بعد ذلك استعادة سجلّ الرجوع والوجهات عند الانتقال إلى تلك الوجهة
في وقت لاحق. يتيح لك ذلك الاحتفاظ بالحالة لوجهة معيّنة والحصول على حِزم احتياطية متعددة.
لتنفيذ ذلك آليًا، حدِّد saveState = true عند إضافة popUpTo إلى خيارات التنقّل.
يمكنك أيضًا تحديد restoreState = true في خيارات التنقّل من أجل
استعادة حزمة الخلف تلقائيًا والحالة المرتبطة بالوجهة.
على سبيل المثال:
navController.navigate(
route = route,
navOptions = navOptions {
popUpTo<A>{ saveState = true }
restoreState = true
}
)
لتفعيل حفظ الحالة واستعادتها في XML، حدِّد popUpToSaveState على النحو true
وrestoreState على النحو true في action المرتبط.
مثال على الإنشاء
في ما يلي مثال كامل على ذلك في 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()، راجِع دليل التنقّل باستخدام الخيارات.
مثال بتنسيق 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"/>
الظهور باستخدام الإجراءات
عند التنقّل باستخدام إجراء، يمكنك اختياريًا إزالة وجهات إضافية من حزمة الخلفية. على سبيل المثال، إذا كان تطبيقك يتضمّن مسار تسجيل دخول أولي، عليك إزالة جميع الوجهات ذات الصلة بتسجيل الدخول من الأنشطة السابقة بعد أن يسجّل المستخدم الدخول، وذلك حتى لا يعود المستخدمون إلى مسار تسجيل الدخول عند النقر على زر الرجوع.
موادّ إضافية للقراءة
لمزيد من المعلومات، يُرجى الاطّلاع على الصفحات التالية:
- التنقّل الدائري: تعرَّف على كيفية تجنُّب تكدّس سجلّ الرجوع في الحالات التي تكون فيها مسارات التنقّل دائرية.
- وجهات مربّعات الحوار: يمكنك الاطّلاع على كيفية إضافة اعتبارات فريدة إلى طريقة إدارة سجلّ الرجوع عند استخدام وجهات مربّعات الحوار.