नेस्ट किए गए ग्राफ़

आम तौर पर, आपके ऐप्लिकेशन में लॉगिन फ़्लो, विज़र्ड या अन्य सबफ़्लो को नेस्ट किए गए नेविगेशन ग्राफ़ के तौर पर दिखाया जाता है. सेल्फ़-कंटेन किए गए सबनेविगेशन फ़्लो को इस तरह नेस्ट करने से, आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) के मुख्य फ़्लो को समझना और मैनेज करना आसान हो जाता है.

इसके अलावा, नेस्ट किए गए ग्राफ़ को दोबारा इस्तेमाल किया जा सकता है. इनसे एनकैप्सुलेशन का एक लेवल भी मिलता है. नेस्ट किए गए ग्राफ़ के बाहर मौजूद डेस्टिनेशन का, नेस्ट किए गए ग्राफ़ के अंदर मौजूद किसी भी डेस्टिनेशन पर सीधे तौर पर ऐक्सेस नहीं होता. इसके बजाय, उन्हें नेस्ट किए गए ग्राफ़ पर navigate() करना चाहिए. इससे, ग्राफ़ के बाकी हिस्से पर असर डाले बिना, इंटरनल लॉजिक में बदलाव किया जा सकता है.

उदाहरण

आपके ऐप्लिकेशन का टॉप-लेवल नेविगेशन ग्राफ़, उस शुरुआती डेस्टिनेशन से शुरू होना चाहिए जो उपयोगकर्ता को ऐप्लिकेशन लॉन्च करने पर दिखती है. इसमें वे डेस्टिनेशन शामिल होने चाहिए जो उपयोगकर्ता को आपके ऐप्लिकेशन में अलग-अलग जगहों पर जाने पर दिखती हैं.

पहली इमेज. टॉप-लेवल नेविगेशन ग्राफ़.

पहली इमेज में दिखाए गए टॉप-लेवल नेविगेशन ग्राफ़ को उदाहरण के तौर पर लें. मान लें कि आपको यह ज़रूरी बनाना है कि उपयोगकर्ता को title_screen और register स्क्रीन सिर्फ़ तब दिखें, जब ऐप्लिकेशन पहली बार लॉन्च हो. इसके बाद, उपयोगकर्ता की जानकारी सेव हो जाती है. साथ ही, ऐप्लिकेशन के बाद के लॉन्च में, आपको उन्हें सीधे match स्क्रीन पर ले जाना चाहिए.

सबसे सही तरीका यह है कि match स्क्रीन को टॉप-लेवल नेविगेशन ग्राफ़ का स्टार्ट डेस्टिनेशन सेट करें. साथ ही, टाइटल और रजिस्टर स्क्रीन को नेस्ट किए गए ग्राफ़ में ले जाएं. जैसा कि पहली इमेज में दिखाया गया है:

दूसरी इमेज. टॉप-लेवल नेविगेशन ग्राफ़ में अब नेस्ट किया गया ग्राफ़ शामिल है.

मैच स्क्रीन लॉन्च होने पर, देखें कि कोई रजिस्टर किया गया उपयोगकर्ता है या नहीं. अगर उपयोगकर्ता ने रजिस्टर नहीं किया है, तो उसे रजिस्ट्रेशन स्क्रीन पर ले जाएं.

शर्तों के हिसाब से नेविगेशन के परिदृश्यों के बारे में ज़्यादा जानने के लिए, शर्तों के हिसाब से नेविगेशन देखें.

Compose

Compose का इस्तेमाल करके, नेस्ट किया गया नेविगेशन ग्राफ़ बनाने के लिए, NavGraphBuilder.navigation() फ़ंक्शन का इस्तेमाल करें. ग्राफ़ में डेस्टिनेशन जोड़ते समय, navigation() का इस्तेमाल ठीक उसी तरह किया जाता है जैसे NavGraphBuilder.composable() और NavGraphBuilder.dialog() फ़ंक्शन का इस्तेमाल किया जाता है.

इन दोनों में मुख्य अंतर यह है कि navigation से नया डेस्टिनेशन बनाने के बजाय, नेस्ट किया गया ग्राफ़ बनता है. इसके बाद, नेस्ट किए गए ग्राफ़ में डेस्टिनेशन जोड़ने के लिए, navigation() के लैम्डा में composable() और dialog() को कॉल करें.

देखें कि Compose का इस्तेमाल करके, नीचे दिया गया स्निपेट, दूसरी इमेज में दिखाए गए ग्राफ़ को कैसे लागू करता है:

// 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. कॉन्टेक्स्ट मेन्यू खोलने के लिए, राइट-क्लिक करें. इसके बाद, नेस्ट किए गए ग्राफ़ में ले जाएं > नया ग्राफ़ चुनें. डेस्टिनेशन, नेस्ट किए गए ग्राफ़ में शामिल हो जाते हैं. दूसरी इमेज में, नेविगेशन एडिटर में नेस्ट किया गया ग्राफ़ दिखाया गया है:

    दूसरी इमेज. नेविगेशन एडिटर में नेस्ट किया गया ग्राफ़
  3. नेस्ट किए गए ग्राफ़ पर क्लिक करें. एट्रिब्यूट पैनल में ये एट्रिब्यूट दिखते हैं:

    • टाइप, जिसमें "नेस्ट किया गया ग्राफ़" शामिल है
    • आईडी, जिसमें नेस्ट किए गए ग्राफ़ के लिए सिस्टम से असाइन किया गया आईडी शामिल है. इस आईडी का इस्तेमाल, आपके कोड से नेस्ट किए गए ग्राफ़ को रेफ़र करने के लिए किया जाता है.
  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> एलिमेंट का इस्तेमाल करके, एक ग्राफ़ को दूसरे ग्राफ़ में शामिल किया जा सकता है. इससे, शामिल किए गए ग्राफ़ को किसी अलग मॉड्यूल या प्रोजेक्ट में पूरी तरह से तय किया जा सकता है. इससे, दोबारा इस्तेमाल करने की सुविधा ज़्यादा मिलती है.

नीचे दिया गया स्निपेट दिखाता है कि <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">

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

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