يستخدم مكوّن التنقّل رسمًا بيانيًا للتنقّل لإدارة ميزة التنقّل في تطبيقك. الرسم البياني للتنقّل هو بنية بيانات تحتوي على كل وجهة في تطبيقك والروابط بينها.
أنواع الوجهات
هناك ثلاثة أنواع عامة من الوجهات: المستضافة والمحادثة والنشاط. يوضّح الجدول التالي أنواع الوجهات الثلاثة هذه والغرض منها.
النوع |
الوصف |
حالات الاستخدام |
---|---|---|
مستضافة |
تملأ العنصر مساحة مضيف التنقّل بالكامل. وهذا يعني أنّ حجم الوجهة المستضافة هو نفسه حجم مضيف التنقّل، ولا تظهر الوجهات السابقة. |
الشاشة الرئيسية والشاشة التفصيلية |
مربّع حوار |
تعرِض مكونات واجهة المستخدم التي تظهر على سطح الشاشة. لا ترتبط واجهة المستخدم هذه بموقع مضيف التنقّل أو حجمه. تظهر الوجهات السابقة أسفل الوجهة. |
التنبيهات والاختيارات والنماذج |
النشاط |
يمثّل شاشات أو ميزات فريدة داخل التطبيق. |
أن تكون بمثابة نقطة خروج من الرسم البياني للتنقّل الذي يشغّل نشاط Android جديدًا تتم إدارته بشكل منفصل عن مكوّن التنقّل في عملية تطوير التطبيقات الحديثة لنظام التشغيل Android، يتألف التطبيق من نشاط واحد. لذلك، من الأفضل استخدام وجهات الأنشطة عند التفاعل مع أنشطة تابعة لجهات خارجية أو كجزء من عملية نقل البيانات. |
يحتوي هذا المستند على أمثلة على الوجهات المستضافة، وهي الوجهات الأكثر شيوعًا وأهميتها. اطّلِع على الأدلة التالية للحصول على معلومات عن الوجهات الأخرى:
الأطر
على الرغم من أنّ سير العمل العام نفسه ينطبق في كل الحالات، تعتمد الطريقة الدقيقة لإنشاء مضيف تنقّل ورسم بياني على إطار عمل واجهة المستخدم الذي تستخدمه.
- الإنشاء: استخدِم العنصر القابل للتركيب
NavHost
. أضِفNavGraph
إليه باستخدام Kotlin DSL. يمكنك إنشاء الرسم البياني بطريقتَين:- كجزء من NavHost: يمكنك إنشاء مخطّط التنقّل مباشرةً كأحد
أجزاء إضافة
NavHost
. - برمجيًا: استخدِم الطريقة
NavController.createGraph()
لإنشاءNavGraph
ونقله إلىNavHost
مباشرةً.
- كجزء من NavHost: يمكنك إنشاء مخطّط التنقّل مباشرةً كأحد
أجزاء إضافة
- المقاطع: عند استخدام المقاطع مع إطار عمل واجهة مستخدم طرق العرض، استخدِم
NavHostFragment
كمضيف. هناك عدة طرق لإنشاء ملف رسومي للتنقّل:- بشكل آلي: استخدِم Kotlin DSL لإنشاء
NavGraph
وتطبيقه مباشرةً علىNavHostFragment
.- إنّ دالة
createGraph()
المستخدَمة مع Kotlin DSL لكل من المقاطع وCompose هي نفسها.
- إنّ دالة
- XML: يمكنك كتابة مضيف التنقّل والرسم البياني مباشرةً في ملف XML.
- محرر "استوديو Android": استخدِم محرِّر واجهة المستخدم الرسومية في "استوديو Android" ل إنشاء الرسم البياني وتعديله كملف موارد XML.
- بشكل آلي: استخدِم Kotlin DSL لإنشاء
إنشاء
في Compose، استخدِم كائنًا أو فئة قابلة للتسلسل لتحديد مسار. يصف المسار كيفية الوصول إلى وجهة معيّنة، ويحتوي على جميع المعلومات التي تتطلّبها الوجهة.
استخدِم التعليق التوضيحي @Serializable
لإنشاء طريَق برمجية ضرورية لتحويل البيانات إلى سلسلة وتحويلها من سلسلة لأنواع المسارات تلقائيًا. يتم توفير هذا التعليق التوضيحي
من خلال مكوّن Kotlin Serialization
الإضافي. اتّبِع هذه
التعليمات لإضافة هذا المكوّن الإضافي.
بعد تحديد مساراتك، استخدِم العنصر القابل للتجميع NavHost
لإنشاء
رسم بياني للتنقّل. راجِع المثال التالي:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- يمثّل العنصر القابل للتسلسل كلّ من المسارين
Profile
وFriendsList
. - تُرسِل المكالمة إلى العنصر القابل للتجميع
NavHost
NavController
ومسارًا لوجهة البداية. - تؤدي دالة lambda التي تم تمريرها إلى
NavHost
في النهاية إلى استدعاءNavController.createGraph()
وإرجاعNavGraph
. - يتم تقديم كل مسار كوسيطة نوع لمحاولة
NavGraphBuilder.composable<T>()
التي تضيف الوجهة إلىNavGraph
الناتج. - دالة lambda التي تم تمريرها إلى
composable
هي ما يعرضهNavHost
لتلك الوجهة.
فهم دالة lambda
لفهم دالة lambda التي تنشئ NavGraph
بشكل أفضل، ننصحك بأن تضع في اعتبارك أنّه لإنشاء الرسم البياني نفسه الوارد في المقتطف السابق، يمكنك إنشاء NavGraph
بشكل منفصل باستخدام NavController.createGraph()
ونقله إلى NavHost
مباشرةً:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
تمرير الوسيطات
إذا كنت بحاجة إلى تمرير البيانات إلى وجهة، حدِّد المسار باستخدام فئة
تتضمّن مَعلمات. على سبيل المثال، مسار Profile
هو فئة بيانات تتضمّن مَعلمة name
.
@Serializable
data class Profile(val name: String)
كلما احتجت إلى تمرير وسيطات إلى هذا الوجهة، يمكنك إنشاء مثيل لفئة المسار، مع تمرير الوسائط إلى الدالة الإنشائية للفئة.
بالنسبة إلى الوسيطات الاختيارية، أنشئ حقولًا يمكن أن تحتوي على قيمة فارغة مع قيمة تلقائية.
@Serializable
data class Profile(val nickname: String? = null)
الحصول على مثيل المسار
يمكنك الحصول على مثيل المسار باستخدام NavBackStackEntry.toRoute()
أو
SavedStateHandle.toRoute()
. عند إنشاء وجهة باستخدام
composable()
، يكون NavBackStackEntry
متاحًا كمَعلمة.
@Serializable
data class Profile(val name: String)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(name = profile.name) }
}
يُرجى ملاحظة ما يلي في المقتطف التالي:
- يحدِّد مسار
Profile
الوجهة الأساسية في gráph التنقّل، مع استخدام"John Smith"
كوسيطةname
. - الوجهة نفسها هي مجموعة
composable<Profile>{}
. - يأخذ العنصر القابل للتجميع
ProfileScreen
قيمةprofile.name
لمَعلمةname
الخاصة به. - وهكذا، يتم تمرير القيمة
"John Smith"
إلىProfileScreen
.
مثال بسيط
مثال كامل على عمل NavController
وNavHost
معًا:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
profile: Profile
onNavigateToFriendsList: () -> Unit,
) {
Text("Profile for ${profile.name}")
Button(onClick = { onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Profile(name = "John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(
profile = profile,
onNavigateToFriendsList = {
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
onNavigateToProfile = {
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
كما يوضّح المقتطف، بدلاً من تمرير NavController
إلى
العناصر القابلة للتجميع، عليك عرض حدث على NavHost
. وهذا يعني أنّ العناصر القابلة للتجميع يجب أن تملك مَعلمة من النوع () -> Unit
يُمرِّر لها NavHost
دالة lambda
تستدعي NavController.navigate()
.
الأجزاء
كما هو موضّح في الأقسام السابقة، عند استخدام الأجزاء، يتوفّر لك خيار إنشاء رسم بياني للتنقّل آليًا باستخدام Kotlin DSL أو XML أو محرِّر Android Studio.
توضّح الأقسام التالية هذه الأساليب المختلفة بالتفصيل.
آليًا
توفّر Kotlin DSL طريقة آلية لإنشاء رسم بياني للتنقّل باستخدام المقاطع. وهذا الإجراء أكثر حداثة وتنظيمًا من استخدام ملف موارد XML.
راجِع المثال التالي الذي ينفِّذ رسمًا بيانيًا للتنقّل على شاشتَين.
أولاً، يجب إنشاء NavHostFragment
، والذي يجب ألا يتضمّن
عنصر app:navGraph
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
بعد ذلك، مرِّر id
من NavHostFragment
إلى
NavController.findNavController
. يؤدي ذلك إلى ربط NavController بمحاولة
NavHostFragment
.
بعد ذلك، تربط الدعوة إلى NavController.createGraph()
الرسم البياني بجدول NavController
وبالتالي أيضًا بجدول NavHostFragment
:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Profile(name = "John Smith")
) {
// Associate each destination with one of the route constants.
fragment<ProfileFragment, Profile> {
label = "Profile"
}
fragment<FriendsListFragment, FriendsList>() {
label = "Friends List"
}
// Add other fragment destinations similarly.
}
يشبه استخدام لغة DSL بهذه الطريقة سير العمل الموضّح في
القسم السابق عن الإنشاء. على سبيل المثال، في كل من هنا وهناك، تنشئ الدالة
NavController.createGraph()
القيمة NavGraph
. وبالمثل، بينما تُضيف
NavGraphBuilder.composable()
وجهات قابلة للتجميع إلى الرسم البياني، تُضيف
NavGraphBuilder.fragment()
هنا وجهة للفقرة.
لمزيد من المعلومات عن كيفية استخدام Kotlin DSL، اطّلِع على مقالة إنشاء رسم بياني باستخدام لغة برمجة مختصرة NavGraphBuilder.
XML
يمكنك كتابة ملف XML بنفسك مباشرةً. يعكس المثال التالي مثال الشاشتَين من القسم السابق وهو مكافئ له.
أولاً، أنشئ NavHostFragment
. ويُستخدَم هذا العنصر كمضيف للتنقّل يحتوي على الرسم البياني الفعلي للتنقّل.
الحد الأدنى لتنفيذ NavHostFragment
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
يحتوي NavHostFragment
على السمة app:navGraph
. استخدِم هذه السمة
لربط الرسم البياني للتنقّل بمضيف التنقّل. في ما يلي مثال على كيفية تنفيذ الرسم البياني:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/profile">
<fragment
android:id="@+id/profile"
android:name="com.example.ProfileFragment"
android:label="Profile">
<!-- Action to navigate from Profile to Friends List. -->
<action
android:id="@+id/action_profile_to_friendslist"
app:destination="@id/friendslist" />
</fragment>
<fragment
android:id="@+id/friendslist"
android:name="com.example.FriendsListFragment"
android:label="Friends List" />
<!-- Add other fragment destinations similarly. -->
</navigation>
يمكنك استخدام الإجراءات لتحديد الربط بين الوجهات المختلفة. في
هذا المثال، يحتوي المقتطف profile
على إجراء يؤدي إلى الانتقال إلى
friendslist
. لمزيد من المعلومات، اطّلِع على استخدام إجراءات التنقّل والمقتطفات.
محرِّر
يمكنك إدارة الرسم البياني للتنقّل في تطبيقك باستخدام "أداة تعديل التنقّل" في IDE
Android Studio. هذه أداة رسومية أساسية يمكنك استخدامها لإنشاء ملف NavigationFragment
XML وتعديله، كما هو موضّح في القسم السابق.
لمزيد من المعلومات، يُرجى الاطّلاع على محرر التنقّل.
الرسوم البيانية المتداخلة
يمكنك أيضًا استخدام الرسوم البيانية المتداخلة. ويشمل ذلك استخدام رسم بياني كوجهة تنقّل. لمزيد من المعلومات، يُرجى الاطّلاع على الرسوم البيانية المُدمجة.
مراجع إضافية
لمزيد من المفاهيم الأساسية للتنقّل، اطّلِع على الأدلة التالية:
- نظرة عامة: احرص على قراءة النظرة العامة على ملف تعريف الارتباط Navigation.
- وجهات الأنشطة: أمثلة على كيفية تنفيذ الوجهات التي تنقل المستخدم إلى الأنشطة
- الوجهات التي تؤدي إلى مربّع حوار: أمثلة على كيفية إنشاء وجهات تؤدي إلى توجيه المستخدِم إلى مربّع حوار
- الانتقال إلى وجهة: دليل تفصيلي يتناول كيفية الانتقال من وجهة إلى أخرى
- الرسوم البيانية المُدمجة: دليل مفصّل حول كيفية دمج رسم بياني navigable واحد في رسم بياني آخر