تصميم الرسم البياني للتنقل

يستخدِم مكوِّن التنقّل رسمًا بيانيًا للتنقل لإدارة إعدادات التنقل. الرسم البياني للتنقل هو هيكل بيانات يحتوي على كل الوجهة داخل تطبيقك والروابط بينها.

أنواع الوجهة

هناك ثلاثة أنواع عامة من الوجهات: المستضافة ومربّع الحوار والنشاط. تشير رسالة الأشكال البيانية يوضّح الجدول التالي أنواع الوجهات الثلاثة هذه والغرض منها.

النوع

الوصف

حالات الاستخدام

مستضاف

يملأ مضيف التنقل بالكامل. وهذا يعني أنّ حجم وجهة مستضافة يكون مماثلاً لحجم مضيف التنقّل ولا تكون الوجهات السابقة مرئية.

الشاشة الرئيسية وشاشات التفاصيل.

مربّع حوار

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

التنبيهات والتحديدات والنماذج.

النشاط

يمثل شاشات أو ميزات فريدة داخل التطبيق.

تعمل كنقطة خروج للرسم البياني للتنقل الذي يبدأ نشاطًا جديدًا على Android تتم إدارته بشكل منفصل عن مكوِّن التنقل.

في عمليات تطوير Android الحديثة، يتألف التطبيق من نشاط واحد. وبالتالي، من الأفضل استخدام وجهات الأنشطة عند التفاعل مع أنشطة تابعة لجهات خارجية أو كجزء من عملية نقل البيانات.

ويحتوي هذا المستند على أمثلة على الوجهات المستضافة، الوجهات المشتركة والأساسية يمكنك الاطلاع على الأدلة التالية للحصول على معلومات حول الوجهات الأخرى:

أُطر العمل

وعلى الرغم من أن نفس سير العمل العام ينطبق في كل الحالات، إلا أن كيفية إنشاء مضيف التنقل والرسم البياني على إطار عمل واجهة المستخدم الذي تستخدمه.

  • الإنشاء: استخدِم عنصر NavHost القابل للإنشاء. أضِف NavGraph إليها باستخدام Kotlin DSL. يمكنك إنشاء الرسم البياني بطريقتين:
    • كجزء من NavHost: يمكنك إنشاء الرسم البياني للتنقل مباشرةً باسم جزء من إضافة NavHost.
    • آليًا: استخدِم الطريقة NavController.createGraph() لإنشاء NavGraph وتمريره إلى NavHost مباشرةً.
  • الأجزاء: عند استخدام الأجزاء مع إطار عمل واجهة المستخدم لطرق العرض، استخدِم NavHostFragment كمضيف. هناك عدة طرق لإنشاء شريط الرسم البياني:
    • برمجيًا: يمكنك استخدام Kotlin DSL لإنشاء NavGraph تطبيقها مباشرةً على NavHostFragment.
      • الدالة createGraph() المستخدمة مع Kotlin DSL لكل منهما الأجزاء و Compose هي نفسها.
    • XML: يمكنك كتابة مضيف التنقل والرسم البياني مباشرةً بتنسيق XML.
    • أداة التعديل في "استوديو Android": يمكنك استخدام أداة تعديل واجهة المستخدم الرسومية في "استوديو Android" من أجل: إنشاء وتعديل الرسم البياني كملف مورد XML.

إنشاء

في Compose، استخدِم فئة أو كائنًا متسلسلاً لتحديد مسار. المسار A ويصف طريقة الوصول إلى وجهة ما، ويحتوي على جميع المعلومات التي المطلوبة للوصول إلى الوجهة. بعد تحديد مساراتك، استخدِم 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.
}
  1. يمثل الكائن المتسلسل كل مسار من المسارين، Profile و FriendsList
  2. المكالمة إلى NavHost القابل للإنشاء تجتاز NavController ومسار لوجهة البداية.
  3. تم تمرير دالة lambda إلى NavHost في النهاية. NavController.createGraph() وإرجاع NavGraph
  4. يتم توفير كل مسار كوسيطة نوع NavGraphBuilder.composable<T>() الذي يضيف الوجهة إلى نتيجة NavGraph.
  5. إنّ بطاقة 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)

كلما احتجت إلى تمرير الوسيطات إلى هذه الوجهة، يمكنك إنشاء مثيل لفئة المسار، مع تمرير الوسائط إلى الدالة الإنشائية للفئة.

الحصول على مثيل المسار

يمكنك الحصول على مثيل المسار باستخدام 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 وجهة البدء في شريط التنقّل. رسم بياني، مع "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"

وتوضح الأقسام التالية بالتفصيل هذه الأساليب المختلفة.

آليًا

توفر لغة 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 بهذه الطريقة إلى حد كبير سير العمل الموضح في القسم السابق حول Compose على سبيل المثال، هناك وهنا، تنشئ الدالة NavController.createGraph() السمة NavGraph. وبالمثل، في حين أن يضيف NavGraphBuilder.composable() وجهات قابلة للإنشاء إلى الرسم البياني هنا يضيف NavGraphBuilder.fragment() وجهة للأجزاء.

لمزيد من المعلومات حول كيفية استخدام Kotlin DSL، راجع إنشاء رسم بياني باستخدام NavGraphBuilder DSL.

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 لمزيد من المعلومات، راجِع استخدام إجراءات التنقل الأجزاء.

محرِّر

يمكنك إدارة الرسم البياني للتنقّل في تطبيقك باستخدام "محرِّر التنقل" في "استوديو Android". وهي في الأساس واجهة مستخدم تصويرية يمكنك استخدامها لإنشاء وتعديل NavigationFragment بتنسيق XML، كما هو موضّح في القسم السابق.

لمزيد من المعلومات، يُرجى الاطّلاع على محرر التنقل.

الرسوم البيانية المتداخلة

يمكنك أيضًا استخدام الرسوم البيانية المتداخلة. يتضمن هذا استخدام الرسم البياني كتنقل الوجهة. لمزيد من المعلومات، يُرجى الاطّلاع على الرسومات البيانية المضمَّنة.

قراءات إضافية

للتعرّف على مزيد من مفاهيم التنقّل الأساسية، يُرجى الاطّلاع على الأدلة التالية: