يتضمّن العمود NavController
"حزمة خلفية" تتضمّن الوجهات التي زارها المستخدم. أثناء انتقال المستخدِم إلى الشاشات في تطبيقك، تُضيف
NavController
الوجهات من وإلى الحزمة الخلفية وتزيلها.
في كونك مكدسًا، يكون المكدس الخلفي عبارة عن هيكل بيانات "آخر دخول، أولاً".
وبالتالي، تدفع السمة NavController
العناصر إلى أعلى المكدس وينبثقها.
السلوك الأساسي
في ما يلي الحقائق الأساسية التي يجب مراعاتها في ما يتعلق بسلوك حزمة الخلفية:
- الوجهة الأولى: عندما يفتح المستخدم التطبيق،
يدفع
NavController
الوجهة الأولى إلى أعلى حزمة الخلفية. - إرسال البيانات إلى الحزمة: تدفع كل مكالمة
NavController.navigate()
الوجهة المحدّدة إلى أعلى الحزمة. - إظهار الوجهة الأولى: يؤدي النقر على السهم المتّجه للأعلى أو Back (رجوع) إلى استدعاء الطريقتين
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()
}
جافا
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
الانتقال إلى وجهة معيّنة
لإزالة الوجهات من الحزمة الخلفية عند الانتقال من وجهة إلى أخرى، أضِف وسيطة popUpTo()
إلى استدعاء دالة navigate()
المرتبط. يطلب popUpTo()
من مكتبة التنقل إزالة بعض الوجهات
من الحزمة الخلفية كجزء من طلب navigate()
. قيمة المَعلمة هي معرّف وجهة على المكدس الخلفي ويمكن أن يكون المعرّف عددًا صحيحًا id
أو سلسلة route
.
يمكنك تضمين وسيطة للمَعلمة inclusive
بالقيمة true
للإشارة إلى أنّ الوجهة التي حدّدتها في popUpTo()
يجب أن تنبثق أيضًا خارج المكدس.
لتنفيذ ذلك آليًا، مرِّر popUpTo()
إلى navigate()
كجزء من
NavOptions
مع ضبط inclusive
على true
. يعمل هذا في كل من
"إنشاء" و"طرق العرض".
حفظ الحالة عند فتح نافذة منبثقة
عند استخدام popUpTo
للانتقال إلى وجهة معيّنة، يمكنك اختياريًا حفظ
حالات جميع الوجهات المعروضة في الحزمة الخلفية.
لتفعيل هذا الخيار، حدِّد popUpToSaveState
على أنه true
في action
المرتبط أو اتصل بالرقم NavController.navigate()
.
عند الانتقال إلى وجهة معيّنة، يمكنك أيضًا تحديد restoreSaveState
كـ
true
لاستعادة الحالة المرتبطة بالوجهة تلقائيًا في السمة
destination
.
مثال على 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"/>
أمثلة على الإنشاء
فيما يلي مثال كامل على ذلك في Compose:
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: String = "destination_a"
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable("destination_a") {
DestinationA(
onNavigateToB = {
// 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") {
inclusive = true
saveState = true
}
}
},
)
}
composable("destination_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()
، راجع
دليل التنقل باستخدام الخيارات.
التمييز باستخدام الإجراءات
عند التنقل باستخدام إجراء، يمكنك اختياريًا إزالة وجهات إضافية من الحزمة الخلفية. على سبيل المثال، إذا كان تطبيقك يتضمن تدفقًا مبدئيًا لتسجيل الدخول، فبمجرد أن يسجّل المستخدم الدخول، يجب إزالة جميع الوجهات المتعلقة بتسجيل الدخول من الحزمة القديمة بحيث لا يعيد زر الرجوع المستخدمين إلى مسار تسجيل الدخول.
قراءة إضافية
لمزيد من المعلومات، يُرجى الاطّلاع على الصفحات التالية:
- التنقل الدائري: تعرَّف على كيفية تجنُّب ظهور تكديس خلفية مكتظة بالكامل في الحالات التي تكون فيها مسارات التنقّل دائرية.
- وجهات مربّع الحوار: تعرَّف على كيفية تحديد وجهات مربعات الحوار باعتبارات فريدة حول كيفية إدارة الحزمة السابقة.