طراحی نمودار پیمایش

مؤلفه پیمایش از نمودار پیمایش برای مدیریت پیمایش برنامه‌تان استفاده می‌کند. نمودار پیمایش ساختار داده‌ای است که شامل هر مقصد در برنامه شما و اتصالات بین آن‌ها است.

انواع مقصد

سه نوع کلی مقصد وجود دارد: میزبانی‌شده، گفتگو، و فعالیت. جدول زیر این سه نوع مقصد و اهداف آن‌ها را شرح می‌دهد.

نوع

شرح

موارد استفاده

میزبانی‌شده

کل میزبان پیمایش را پر می‌کند. یعنی اندازه مقصد میزبانی‌شده با اندازه میزبان پیمایش یکسان است و مقصدهای قبلی قابل‌مشاهده نیستند.

صفحه‌های اصلی و جزئیات.

کادر گفتگو

عناصر واسط کاربر هم‌پوشان را ارائه می‌دهد. این واسط کاربر به مکان میزبان پیمایش یا اندازه آن وابسته نیست. مقصدهای قبلی در زیر مقصد قابل‌مشاهده است.

هشدارها، انتخاب‌ها، فرم‌ها.

فعالیت

صفحه‌ها یا ویژگی‌های منحصربه‌فردی را در برنامه نشان دهد.

به‌عنوان نقطه خروج از نمودار پیمایش عمل کند که فعالیت Android جدیدی را شروع می‌کند که جدا از مؤلفه «پیمایش» مدیریت می‌شود.

در توسعه مدرن Android، برنامه از یک فعالیت تشکیل شده است. بنابراین، مقصدهای فعالیت بهترین کاربرد را هنگام تعامل با فعالیت‌های شخص ثالث یا به‌عنوان بخشی از فرایند انتقال دارند.

این سند حاوی نمونه‌هایی از مقصدهای میزبانی‌شده است که رایج‌ترین و اساسی‌ترین مقصدها هستند. برای اطلاعات درباره مقصدهای دیگر، راهنماهای زیر را ببینید:

چارچوب

اگرچه گردش کار کلی یکسانی در هر مورد اعمال می‌شود، اما نحوه ایجاد دقیق آن یک میزبان ناوبری و نمودار به چارچوب رابط کاربری که استفاده می کنید بستگی دارد.

  • Compose: از NavHost composable استفاده کنید. بااستفاده از Kotlin DSL، NavGraph به آن اضافه کنید. به دو روش می‌توانید نمودار ایجاد کنید:
    • به‌عنوان بخشی از NavHost: نمودار پیمایش را مستقیماً به‌عنوان بخشی از افزودن NavHost بسازید.
    • برنامه‌نویسی: از روش NavController.createGraph() برای ایجاد NavGraph و ارسال مستقیم آن به NavHost استفاده کنید.
  • تکه‌ها: هنگام استفاده از تکه‌ها با چارچوب واسط کاربر نماها، از NavHostFragment به‌عنوان میزبان استفاده کنید. چندین روش برای ایجاد نمودار پیمایش وجود دارد:
    • برنامه‌نویسی: از Kotlin DSL برای ایجاد NavGraph و اعمال مستقیم آن روی NavHostFragment استفاده کنید.
      • تابع createGraph() که با Kotlin DSL برای هر دو تکه و Compose استفاده می‌شود یکسان است.
    • XML: میزبان و نمودار پیمایش را مستقیماً در XML بنویسید.
    • ویرایشگر «استودیو Android»: از ویرایشگر GUI در «استودیو Android» برای ایجاد و تنظیم نمودار به‌عنوان فایل منبع XML استفاده کنید.

نوشتن

در Compose، از یک کلاس یا شیء قابل‌سریال‌سازی برای تعریف مسیر استفاده کنید. مسیر نحوه رسیدن به مقصد را شرح می‌دهد و حاوی همه اطلاعاتی است که مقصد نیاز دارد.

از حاشیه‌نویسی @Serializable برای ایجاد خودکار روش‌های سریال‌سازی و سریال‌زدایی لازم برای انواع مسیرهایتان استفاده کنید. این حاشیه‌نویسی را افزونه Kotlin Serialization ارائه کرده است. برای افزودن این افزونه، این دستورالعمل‌ها را دنبال کنید.

پس‌از تعریف مسیرها، از ترکیب‌پذیر 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 برای آن مقصد نمایش می‌دهد.

آشنایی با لامبدا

برای درک بهتر لامبدایی که 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)

هرگاه لازم باشد آرگومان‌ها را به آن مقصد ارسال کنید، نمونه‌ای از کلاس مسیر خود ایجاد می‌کنید و آرگومان‌ها را به سازنده کلاس ارسال می‌کنید.

برای آرگومان‌های اختیاری، فیلدهای تهی‌پذیر با مقدار پیش‌فرض ایجاد کنید.

@Serializable
data class Profile(val nickname: String? = null)

دریافت نمونه مسیر

می‌توانید نمونه مسیر را با 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 برای آن یک لامبدا ارسال می‌کند که 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 Studio مدیریت کنید. این درواقع یک GUI است که می‌توانید از آن برای ایجاد و ویرایش NavigationFragment XML خود استفاده کنید، همان‌طور که در بخش قبلی دیده شد.

برای اطلاعات بیشتر، ویرایشگر ناوبری را ببینید.

گراف‌های تودرتو

همچنین می‌توانید از نمودارهای تودرتو استفاده کنید. این شامل استفاده از گراف به‌عنوان مقصد ناوبری است. برای اطلاعات بیشتر، به نمودارهای تودرتو مراجعه کنید.

بیشتر بخوانید

برای مفاهیم اصلی بیشتر درباره پیمایش، راهنماهای زیر را ببینید:

  • نمای کلی: حتماً نمای کلی عمومی مؤلفه «ناوبری» را بخوانید.
  • مقصدهای فعالیت: نمونه‌هایی از نحوه پیاده‌سازی مقصدهایی که کاربر را به فعالیت‌ها می‌برد.
  • مقصدهای کادر گفتگو: نمونه‌هایی از نحوه ایجاد مقصدهایی که کاربر را به کادر گفتگو هدایت می‌کنند.
  • پیمایش به مقصد: راهنمای مفصلی که نحوه پیمایش از یک مقصد به مقصد دیگر را پوشش می‌دهد.
  • نمودارهای تودرتو: راهنمای عمیق درباره نحوه تودرتو کردن یک نمودار پیمایش در نمودار دیگر.