جریانهای ورود به سیستم، ویزاردها یا سایر جریانهای فرعی درون برنامه شما معمولاً به بهترین شکل به صورت نمودارهای ناوبری تو در تو نمایش داده میشوند. با تو در تو کردن جریانهای فرعی مستقل به این روش، جریان اصلی رابط کاربری برنامه شما راحتتر قابل درک و مدیریت است.
علاوه بر این، گرافهای تودرتو قابل استفاده مجدد هستند. آنها همچنین سطحی از کپسولهسازی را فراهم میکنند - مقصدهای خارج از گراف تودرتو به هیچ یک از مقصدهای درون گراف تودرتو دسترسی مستقیم ندارند. در عوض، آنها باید navigate() ، جایی که منطق داخلی میتواند بدون تأثیر بر بقیه گراف تغییر کند.
مثال
نمودار ناوبری سطح بالای برنامه شما باید با مقصد اولیهای که کاربر هنگام اجرای برنامه میبیند شروع شود و شامل مقاصدی باشد که هنگام حرکت در برنامه شما میبیند.

با استفاده از نمودار ناوبری سطح بالا از شکل ۱ به عنوان مثال، فرض کنید میخواهید کاربر را ملزم کنید که فقط هنگام اولین اجرای برنامه، صفحات title_screen و register را ببیند. پس از آن، اطلاعات کاربر ذخیره میشود و در اجراهای بعدی برنامه، باید او را مستقیماً به صفحه تطبیق ببرید.
به عنوان بهترین روش، صفحه تطبیق را به عنوان مقصد شروع نمودار ناوبری سطح بالا تنظیم کنید و صفحات عنوان و ثبت را به یک نمودار تو در تو منتقل کنید، همانطور که در شکل 1 نشان داده شده است:

وقتی صفحه تطبیق ظاهر شد، بررسی کنید که آیا کاربر ثبتنامشدهای وجود دارد یا خیر. اگر کاربر ثبتنام نکرده است، او را به صفحه ثبتنام هدایت کنید.
برای اطلاعات بیشتر در مورد سناریوهای ناوبری مشروط، به ناوبری مشروط مراجعه کنید.
نوشتن
برای ایجاد یک گراف ناوبری تو در تو با استفاده از Compose، از تابع NavGraphBuilder.navigation() استفاده کنید. هنگام افزودن مقصد به یک گراف، navigation() درست مانند NavGraphBuilder.composable() و NavGraphBuilder.dialog() استفاده میکنید.
تفاوت اصلی این است که navigation به جای یک مقصد جدید، یک گراف تودرتو ایجاد میکند. سپس میتوانید composable() و dialog() را درون لامبدا navigation() فراخوانی کنید تا مقاصد را به گراف تودرتو اضافه کنید.
در نظر بگیرید که چگونه قطعه کد زیر، گراف شکل ۲ را با استفاده از 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، میتوانید از ویرایشگر ناوبری (Navigation Editor) برای ایجاد نمودار تو در تو استفاده کنید. برای انجام این کار، مراحل زیر را دنبال کنید:
- در ویرایشگر ناوبری، کلید Shift را فشار داده و نگه دارید و روی مقاصدی که میخواهید در نمودار تو در تو قرار دهید کلیک کنید.
برای باز کردن منوی زمینه، کلیک راست کنید و گزینه Move to Nested Graph > New Graph را انتخاب کنید. مقصدها در یک گراف تو در تو محصور شدهاند. شکل 2 یک گراف تو در تو را در ویرایشگر ناوبری نشان میدهد:

شکل ۲. گراف تو در تو در ویرایشگر ناوبری روی نمودار تو در تو کلیک کنید. ویژگیهای زیر در پنل ویژگیها ظاهر میشوند:
- نوع ، که شامل "نمودار تو در تو" است
- ID ، که شامل یک شناسه اختصاص داده شده توسط سیستم برای گراف تو در تو است. این شناسه برای ارجاع به گراف تو در تو از کد شما استفاده میشود.
برای نمایش مقاصد نمودار تو در تو، روی آن دوبار کلیک کنید.
برای نمایش XML روی تب Text کلیک کنید. یک گراف ناوبری تو در تو به گراف اضافه شده است. این گراف ناوبری عناصر
navigationمخصوص به خود را به همراه شناسه (ID) مخصوص به خود و یک ویژگی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>در کد خود، شناسه منبع اکشنی را که گراف ریشه را به گراف تو در تو متصل میکند، ارسال کنید:
کاتلین
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
جاوا
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- به برگه Design برگردید، با کلیک روی Root به نمودار ریشه برگردید.
با 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>