ناوبری به مقصد

مؤلفه Navigation روشی سرراست و عمومی برای پیمایش به مقصد ارائه می‌دهد. این میانجی از طیفی از بافت‌ها و چارچوب‌های میانای کاربر پشتیبانی می‌کند. برای مثال، می‌توانید از مؤلفه Navigation با Compose، نماها، بخش‌ها، فعالیت‌ها، و حتی چارچوب‌های سفارشی میانای کاربر استفاده کنید.

این راهنما توضیح می‌دهد که چگونه می‌توانید از مؤلفه Navigation برای پیمایش به یک مقصد در زمینه‌های مختلف استفاده کنید.

استفاده از NavController

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

صرف‌نظر از اینکه از کدام چارچوب واسط کاربر استفاده می‌کنید، یک تابع واحد وجود دارد که می‌توانید از آن برای پیمایش به مقصد استفاده کنید: NavController.navigate().

بارگذاری‌های بیش‌ازحد زیادی برای navigate() دردسترس است. سرریزی که باید انتخاب کنید با بافت دقیق شما مطابقت دارد. برای مثال، باید از یک سربارگذاری هنگام پیمایش به یک composable و از دیگری هنگام پیمایش به یک نما استفاده کنید.

بخش‌های زیر برخی‌از سربارهای کلیدی navigate() را که می‌توانید استفاده کنید شرح می‌دهد.

پیمایش به composable

برای پیمایش به یک composable، باید از NavController.navigate<T> استفاده کنید. با این اضافه‌بار، navigate() یک متغیر مستقل route تکی می‌گیرد که برای آن نوعی را ارسال می‌کنید. این کلید به‌عنوان کلید مقصد عمل می‌کند.

@Serializable
object FriendsList

navController.navigate(route = FriendsList)

برای پیمایش به یک composable در نمودار پیمایش، ابتدا NavGraph خود را تعریف کنید به‌طوری‌که هر مقصد با یک نوع مطابقت داشته باشد. برای ترکیب‌شدنی‌ها، این کار را با تابع composable() انجام می‌دهید.

نمایش رویدادها از composable

وقتی تابع ترکیب‌پذیر باید به صفحه جدیدی پیمایش کند، نباید مرجعی به NavController به آن ارسال کنید تا بتواند مستقیماً navigate() را فراخوانی کند. طبق اصول جریان داده یک‌سویه (UDF)، ترکیب‌پذیر باید درعوض رویدادی را نشان دهد که NavController آن را مدیریت می‌کند.

به‌عبارت دقیق‌تر، composable شما باید پارامتری از نوع () -> Unit داشته باشد. وقتی با تابع composable() مقصدها را به NavHost اضافه می‌کنید، فراخوانی NavController.navigate() را به composable خود ارسال کنید.

برای نمونه‌ای از این مورد، زیربخش زیر را ببینید.

مثال

برای نمایش بخش‌های قبلی، این نکات را در قطعه کد زیر مشاهده کنید:

  1. هر مقصد در نمودار بااستفاده از یک مسیر ایجاد می‌شود که یک کلاس یا شیء قابل‌سریال‌سازی است که داده‌های موردنیاز آن مقصد را توصیف می‌کند.
  2. ‫MyAppNavHost composable نمونه NavController را نگه می‌دارد.
  3. بنابراین، فراخوانی‌های navigate() باید در آنجا انجام شود و نه در ترکیب‌پذیر پایین‌تری مثل ProfileScreen.
  4. ProfileScreen حاوی دکمه‌ای است که وقتی روی آن کلیک می‌شود، کاربر را به FriendsList هدایت می‌کند. اما خودش با navigate() تماس نمی‌گیرد.
  5. درعوض، دکمه تابعی را فراخوانی می‌کند که به‌عنوان پارامتر onNavigateToFriends نمایش داده می‌شود.
  6. وقتی MyAppNavHost ProfileScreen را به نمودار پیمایش اضافه می‌کند، برای onNavigateToFriends یک لامبدا را که navigate(route = FriendsList) را فراخوانی می‌کند ارسال می‌کند.
  7. این کار تضمین می‌کند که وقتی کاربر دکمه ProfileScreen را فشار می‌دهد، به‌درستی به FriendsListScreen هدایت می‌شود.
@Serializable
object Profile
@Serializable
object FriendsList

@Composable
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = Profile
    ) {
        composable<Profile> {
            ProfileScreen(
                onNavigateToFriends = { navController.navigate(route = FriendsList) },
                /*...*/
            )
        }
        composable<FriendsList> { FriendsListScreen(/*...*/) }
    }
}

@Composable
fun ProfileScreen(
    onNavigateToFriends: () -> Unit,
    /*...*/
) {
    /*...*/
    Button(onClick = onNavigateToFriends) {
        Text(text = "See friends list")
    }
}

پیمایش بااستفاده از شناسه عدد صحیح

برای پیمایش به مقصد بااستفاده از شناسه عدد صحیح، سربارگذاری navigate(int) را فراخوانی کنید. این شناسه منبع کنش یا مقصد را می‌گیرد. تکه‌کد زیر نشان می‌دهد که چگونه می‌توانید از این اضافه‌بار برای پیمایش به ViewTransactionsFragment استفاده کنید:

کاتلین

viewTransactionsButton.setOnClickListener { view ->
  view.findNavController().navigate(R.id.viewTransactionsAction)
}

جاوا

viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
      Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
  }
});

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

پیمایش از Compose در برنامه مبتنی بر Fragment

اگر از Jetpack Compose در معماری «پیمایش» مبتنی بر Fragment استفاده می‌کنید (برای مثال، در برنامه ترکیبی Views و Compose)، نمی‌توانید از مسیرهای Compose ایمن ازنظر تایپی برای پیمایش مستقیم استفاده کنید. درعوض، باید از شناسه‌های عدد صحیح (کنش‌ها) تعریف‌شده در نمودار ناوبری XML استفاده کنید.

برای تغییر مقصدها از کد Compose، رویدادی (لامبدا) را از composable خود نمایش دهید:

@Composable
fun MyScreen(onNavigateToProfile: () -> Unit) {
    Button(onClick = { onNavigateToProfile() }) {
        Text("Go to Profile")
    }
}

در قطعه‌تان، Compose و مؤلفه «پیمایش» مبتنی بر «قطعه» را با فراخوانی NavController «قطعه» هنگام راه‌اندازی رویداد پل کنید:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    return ComposeView(requireContext()).apply {
        setContent {
            MyScreen(onNavigateToProfile = { findNavController().navigate(R.id.nav_profile) })
        }
    }
}

این رویکرد باعث می‌شود که ترکیب‌پذیرهای شما قابل‌استفاده مجدد و قابل‌آزمایش باقی بمانند، زیرا آن‌ها مستقیماً به NavController قطعه وابسته نیستند.

پیمایش بااستفاده از NavDeepLinkRequest

برای پیمایش به مقصد پیوند عمیق ضمنی، از سرریز navigate(NavDeepLinkRequest) استفاده کنید. قطعه کد زیر پیاده‌سازی این روش را ارائه می‌دهد:

کاتلین

val request = NavDeepLinkRequest.Builder
  .fromUri("android-app://androidx.navigation.app/profile".toUri())
  .build()
findNavController().navigate(request)

جاوا

NavDeepLinkRequest request = NavDeepLinkRequest.Builder
  .fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
  .build()
NavHostFragment.findNavController(this).navigate(request)

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

کنش‌ها و انواع MIME

علاوه‌بر Uri، NavDeepLinkRequest از پیوندهای عمیق با کنش‌ها و انواع MIME نیز پشتیبانی می‌کند. برای افزودن کنش به درخواست، از fromAction() یا setAction() استفاده کنید. برای افزودن نوع MIME به درخواست، از fromMimeType() یا setMimeType() استفاده کنید.

برای اینکه NavDeepLinkRequest به‌درستی با مقصد پیوند عمیق ضمنی مطابقت داشته باشد، URI، کنش، و نوع رسانه باید با NavDeepLink در مقصد مطابقت داشته باشند. شناسه‌های منبع یکسان باید با الگو مطابقت داشته باشند، کنش‌ها باید دقیقاً مطابقت داشته باشند، و انواع MIME باید مرتبط باشند. برای مثال، image/jpg با image/\* مطابقت دارد

بافت‌های بیشتر

این سند نحوه استفاده از NavController.navigate() را در رایج‌ترین موارد استفاده پوشش می‌دهد. بااین‌حال، این تابع دارای طیفی از اضافه‌بارها است که می‌توانید در زمینه‌های مختلف و همراه با هر چارچوب رابط کاربری استفاده کنید. برای جزئیات بیشتر درباره این سربارگذاری‌ها، به مستندات مرجع مراجعه کنید.

مطالعه بیشتر

برای اطلاعات بیشتر، صفحه‌های زیر را ببینید: