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

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

علاوة على ذلك، فإن الرسوم البيانية المتداخلة قابلة لإعادة الاستخدام. كما أنها توفر مستوى من التغليف - لا تتمتع الوجهات خارج الرسم البياني المتداخل بالوصول المباشر إلى أي من الوجهات ضمن الرسم البياني المدمج. بدلاً من ذلك، يجب عليه navigate() إلى الرسم البياني المدمج نفسه، حيث يمكن للمنطق الداخلي بدون التأثير في بقية الرسم البياني.

مثال

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

الشكل 1. رسم بياني لمستوى أعلى للتنقل

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

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

الشكل 2. يتضمّن الآن الرسم البياني للتنقّل في المستوى الأعلى رسمًا بيانيًا مدمَجًا.

عند فتح شاشة المطابقة، تحقَّق ممّا إذا كان هناك مستخدِم مسجَّل. في حال حذف إذا لم يكن المستخدم مسجّلاً، انتقِل إلى شاشة التسجيل

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

إنشاء

لإنشاء رسم بياني للتنقل متداخل باستخدام ميزة Compose، استخدم NavGraphBuilder.navigation(). أنت تستخدم navigation() تمامًا NavGraphBuilder.composable() وNavGraphBuilder.dialog() عند إضافة وجهات إلى رسم بياني.

يتمثل الاختلاف الأساسي في أن navigation تنشئ رسمًا بيانيًا متداخلاً بدلاً من وجهة جديدة. يمكنك بعد ذلك الاتصال بـ composable() وdialog() خلال lambda لـ navigation() لإضافة وجهات إلى الرسم البياني المدمج.

ضع في اعتبارك كيفية تنفيذ المقتطف التالي للرسم البياني في الشكل 2 باستخدام الإنشاء:

// Routes
@Serializable object Title
@Serializable object Register

// Route for nested graph
@Serializable object Game

// Routes inside nested graph
@Serializable object Match
@Serializable object InGame
@Serializable object ResultsWinner
@Serializable object GameOver

NavHost(navController, startDestination = Title) {
   composable<Title> {
       TitleScreen(
           onPlayClicked = { navController.navigate(route = Register) },
           onLeaderboardsClicked = { /* Navigate to leaderboards */ }
       )
   }
   composable<Register> {
       RegisterScreen(
           onSignUpComplete = { navController.navigate(route = Game) }
       )
   }
   navigation<Game>(startDestination = Match) {
       composable<Match> {
           MatchScreen(
               onStartGame = { navController.navigate(route = InGame) }
           )
       }
       composable<InGame> {
           InGameScreen(
               onGameWin = { navController.navigate(route = ResultsWinner) },
               onGameLose = { navController.navigate(route = GameOver) }
           )
       }
       composable<ResultsWinner> {
           ResultsWinnerScreen(
               onNextMatchClicked = {
                   navController.navigate(route = Match) {
                       popUpTo(route = Match) { inclusive = true }
                   }
               },
               onLeaderboardsClicked = { /* Navigate to leaderboards */ }
           )
       }
       composable<GameOver> {
           GameOverScreen(
               onTryAgainClicked = {
                   navController.navigate(route = Match) {
                       popUpTo(route = Match) { inclusive = true }
                   }
               }
           )
       }
   }
}

من أجل الانتقال مباشرةً إلى وجهة متداخلة، استخدِم نوع مسار كما تفعل إلى أي وجهة أخرى. وهذا لأن المسارات هي مفهوم عالمي يستخدم تحديد الوجهات التي يمكن لأي شاشة الانتقال إليها:

navController.navigate(route = Match)
.

XML

عند استخدام XML، يمكنك استخدام محرر التنقل لإنشاء رسم بياني مدمج. لإجراء ذلك، يُرجى اتّباع الخطوات التالية:

  1. في محرر التنقل، اضغط مع الاستمرار على مفتاح Shift، وانقر على الوجهات التي تريد تضمينها في الرسم البياني المدمج.
  2. انقر بزر الماوس الأيمن لفتح قائمة السياقات واختر نقل إلى الرسم البياني المتداخلة > رسم بياني جديد: يتم تضمين الوجهات في رسم بياني مدمج. على شكل 2 تعرض رسمًا بيانيًا مدمجًا في محرر التنقل:

    الشكل 2. رسم بياني مدمج في "محرِّر التنقل"
  3. انقر على الرسم البياني المدمج. تظهر السمات التالية في ملف لوحة السمات:

    • النوع الذي يحتوي على "رسم بياني مضمَّن"
    • ID، الذي يحتوي على معرّف يعيّنه النظام للرسم البياني المتداخل. هذا النمط يتم استخدام المعرّف للإشارة إلى الرسم البياني المدمج من التعليمات البرمجية.
  4. انقر مرّتين على الرسم البياني المدمج لعرض وجهاته.

  5. انقر على علامة التبويب نص للتبديل إلى عرض XML. رسم بياني للتنقل متداخل تمت إضافته إلى الرسم البياني. يتضمّن الرسم البياني للتنقّلي هذا navigation الخاص به. مع رقم التعريف الخاص بها وسمة startDestination التي يشير إلى الوجهة الأولى في الرسم البياني المدمج:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
       xmlns:tools="http://schemas.android.com/tools"
       xmlns:android="http://schemas.android.com/apk/res/android"
       app:startDestination="@id/mainFragment">
       <fragment
           android:id="@+id/mainFragment"
           android:name="com.example.cashdog.cashdog.MainFragment"
           android:label="fragment_main"
           tools:layout="@layout/fragment_main" >
           <action
               android:id="@+id/action_mainFragment_to_sendMoneyGraph"
               app:destination="@id/sendMoneyGraph" />
           <action
               android:id="@+id/action_mainFragment_to_viewBalanceFragment"
               app:destination="@id/viewBalanceFragment" />
       </fragment>
       <fragment
           android:id="@+id/viewBalanceFragment"
           android:name="com.example.cashdog.cashdog.ViewBalanceFragment"
           android:label="fragment_view_balance"
           tools:layout="@layout/fragment_view_balance" />
       <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient">
           <fragment
               android:id="@+id/chooseRecipient"
               android:name="com.example.cashdog.cashdog.ChooseRecipient"
               android:label="fragment_choose_recipient"
               tools:layout="@layout/fragment_choose_recipient">
               <action
                   android:id="@+id/action_chooseRecipient_to_chooseAmountFragment"
                   app:destination="@id/chooseAmountFragment" />
           </fragment>
           <fragment
               android:id="@+id/chooseAmountFragment"
               android:name="com.example.cashdog.cashdog.ChooseAmountFragment"
               android:label="fragment_choose_amount"
               tools:layout="@layout/fragment_choose_amount" />
       </navigation>
    </navigation>
    
  6. في الرمز البرمجي، أدخِل رقم تعريف المصدر للإجراء الذي يربط الرسم البياني الجذري. إلى الرسم البياني المتداخل:

Kotlin

view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)

Java

Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
  1. في علامة التبويب التصميم، ارجع إلى الرسم البياني الجذري من خلال النقر على الجذر:

الإشارة إلى الرسوم البيانية الأخرى للتنقل من خلال تضمين

يمكنك أيضًا تقسيم بنية الرسم البياني إلى وحدات، وهي تضمين رسم بياني واحد ضمن أخرى باستخدام عنصر <include> في الرسم البياني للتنقّل الرئيسي. هذا النمط يسمح بتعريف الرسم البياني المتضمن في وحدة أو مشروع منفصل تمامًا، مما يزيد من إمكانية إعادة الاستخدام.

يوضح المقتطف التالي كيفية استخدام <include>:

<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/fragment">

    <strong><include app:graph="@navigation/included_graph" /></strong>

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.myapplication.BlankFragment"
        android:label="Fragment in Root Graph"
        tools:layout="@layout/fragment_blank">
        <strong><action
            android:id="@+id/action_fragment_to_second_graph"
            app:destination="@id/second_graph" /></strong>
    </fragment>

    ...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    <strong>android:id="@+id/second_graph"</strong>
    app:startDestination="@id/includedStart">

    <fragment
        android:id="@+id/includedStart"
        android:name="com.example.myapplication.IncludedStart"
        android:label="fragment_included_start"
        tools:layout="@layout/fragment_included_start" />
</navigation>

مصادر إضافية

لمعرفة المزيد حول التنقل، يُرجى الرجوع إلى الموارد الإضافية التالية.

نماذج

الدروس التطبيقية حول الترميز

الفيديوهات