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

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

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

उदाहरण

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

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

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

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

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

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

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

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

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

  1. नेविगेशन एडिटर में, Shift बटन को दबाकर रखें. इसके बाद, उन डेस्टिनेशन पर क्लिक करें जिन्हें आपको नेस्ट किए गए ग्राफ़ में शामिल करना है.
  2. संदर्भ मेन्यू खोलने के लिए, राइट क्लिक करें. इसके बाद, नेस्ट किए गए ग्राफ़ में ले जाएं > नया ग्राफ़ चुनें. डेस्टिनेशन, नेस्ट किए गए ग्राफ़ में शामिल होते हैं. दूसरी इमेज में, नेविगेशन एडिटर में नेस्ट किया गया ग्राफ़ दिखाया गया है:

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

    • टाइप, जिसमें "नेस्टेड ग्राफ़" शामिल है
    • आईडी, जिसमें नेस्ट किए गए ग्राफ़ के लिए सिस्टम से असाइन किया गया आईडी होता है. इस आईडी का इस्तेमाल, आपके कोड से नेस्ट किए गए ग्राफ़ को रेफ़रंस करने के लिए किया जाता है.
  4. डेस्टिनेशन दिखाने के लिए, नेस्ट किए गए ग्राफ़ पर दो बार क्लिक करें.

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