انتقال Jetpack Navigation به Navigation Compose

Navigation Compose API به شما امکان می‌دهد بین composable در برنامه Compose پیمایش کنید و درعین‌حال از مؤلفه، زیرساخت، و ویژگی‌های Jetpack Navigation بهره ببرید.

این صفحه نحوه انتقال از «پیمایش Jetpack» مبتنی بر Fragment به Navigation Compose را به‌عنوان بخشی از انتقال بزرگ‌تر میانای کاربر مبتنی بر View به Jetpack Compose شرح می‌دهد.

پیش‌نیازهای انتقال

وقتی توانستید همه Fragmentها را با composableهای صفحه مربوطه جایگزین کنید، می‌توانید به Navigation Compose مهاجرت کنید. ترکیب‌شدنی‌های صفحه می‌توانند حاوی ترکیبی از محتوای Compose و View باشند، اما همه مقصدهای پیمایش باید ترکیب‌شدنی باشند تا انتقال Navigation Compose امکان‌پذیر شود. تا آن زمان، باید به استفاده از مؤلفه Fragment-based Navigation در پایگاه کد Compose و نمای هم‌کنش‌پذیر ادامه دهید. برای اطلاعات بیشتر، مستندات تعامل‌پذیری ناوبری را ببینید.

مراحل انتقال

چه از استراتژی انتقال توصیه‌شده ما پیروی کنید یا رویکرد دیگری را درپیش بگیرید، به نقطه‌ای خواهید رسید که همه مقصدهای پیمایش، ترکیب‌پذیرهای صفحه هستند و Fragmentها فقط به‌عنوان محفظه‌های ترکیب‌پذیر عمل می‌کنند. در این مرحله، می‌توانید به Navigation Compose منتقل شوید.

اگر برنامه‌تان ازقبل از الگوی طراحی UDF و راهنمای معماری ما پیروی می‌کند، انتقال به Jetpack Compose و Navigation Compose نباید به بازسازی کد عمده در لایه‌های دیگر برنامه‌تان (به‌جز لایه واسط کاربر) نیاز داشته باشد.

برای انتقال به Navigation Compose، این مراحل را دنبال کنید:

  1. وابستگی Navigation Compose را به برنامه‌تان اضافه کنید.
  2. یک App-level قابل‌ساخت ایجاد کنید و آن را به‌عنوان نقطه ورود Compose به Activity خود اضافه کنید، و آن را جایگزین راه‌اندازی چیدمان View کنید:

    class SampleActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
            setContent {
                SampleApp(/* ... */)
            }
        }
    }

  3. برای هر مقصد پیمایش، نوع ایجاد کنید. از data object برای مقصدهایی که به داده نیاز ندارند و از data class یا class برای مقصدهایی که به داده نیاز دارند استفاده کنید.

    @Serializable data object First
    @Serializable data class Second(val id: String)
    @Serializable data object Third
    

  4. NavController را در جایی راه‌اندازی کنید که همه ترکیب‌پذیرهایی که باید به آن ارجاع دهند به آن دسترسی داشته باشند (این معمولاً داخل ترکیب‌پذیر App شما است). این رویکرد از اصول بالابردن حالت پیروی می‌کند و به شما امکان می‌دهد از NavController به‌عنوان منبع حقیقت برای پیمایش بین صفحه‌های قابل‌ترکیب و حفظ پشته قبلی‌ها استفاده کنید:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
        // ...
    }

  5. NavHost برنامه‌تان را در App قابل‌ساخت ایجاد کنید و navController را ارسال کنید:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
    
        SampleNavHost(navController = navController)
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = First) {
            // ...
        }
    }

  6. composable مقصد را برای ساختن نمودار ناوبری اضافه کنید. اگر هر صفحه قبلاً به Compose منتقل شده باشد، این مرحله فقط شامل استخراج این composableهای صفحه از Fragmentها به مقصدهای composable است:

    class FirstFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            return ComposeView(requireContext()).apply {
                setContent {
                    // FirstScreen(...) EXTRACT FROM HERE
                }
            }
        }
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = First) {
            composable<First> {
                FirstScreen(/* ... */) // EXTRACT TO HERE
            }
            composable<Second> {
                SecondScreen(/* ... */)
            }
            // ...
        }
    }

  7. اگر راهنمایی‌های مربوط به معماری «میانای کاربر Compose» را دنبال کرده‌اید، به‌ویژه نحوه ارسال ViewModel و رویدادهای پیمایش به ساختنی‌ها، گام بعدی تغییر نحوه ارائه ViewModel به هر ساختنی صفحه است. اغلب می‌توانید از تزریق Hilt و نقطه ادغام آن با Compose و Navigation ازطریق hiltViewModel استفاده کنید:

    @Composable
    fun FirstScreen(
        // viewModel: FirstViewModel = viewModel(),
        viewModel: FirstViewModel = hiltViewModel(),
        onButtonClick: () -> Unit = {},
    ) {
        // ...
    }

  8. همه فراخوانی‌های پیمایش findNavController() را با فراخوانی‌های navController جایگزین کنید و آن‌ها را به‌عنوان رویدادهای پیمایش به هر صفحه قابل‌ترکیب ارسال کنید، به‌جای اینکه کل navController را ارسال کنید. این رویکرد از روال‌های مطلوب برای نمایش رویدادها از توابع ترکیب‌پذیر به فراخوانندگان پیروی می‌کند و navController را به‌عنوان منبع واحد حقیقت حفظ می‌کند.

    با ایجاد نمونه‌ای از کلاس مسیر تعریف‌شده برای آن مقصد، می‌توان داده‌ها را به مقصد منتقل کرد. سپس می‌توان آن را مستقیماً از ورودی پشته قبلی‌ها در مقصد یا از ViewModel بااستفاده از SavedStateHandle.toRoute() دریافت کرد.

    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = First) {
            composable<First> {
                FirstScreen(
                    onButtonClick = {
                        // findNavController().navigate(firstScreenToSecondScreenAction)
                        navController.navigate(Second(id = "ABC"))
                    }
                )
            }
            composable<Second> { backStackEntry ->
                val secondRoute = backStackEntry.toRoute<Second>()
                SecondScreen(
                    id = secondRoute.id,
                    onIconClick = {
                        // findNavController().navigate(secondScreenToThirdScreenAction)
                        navController.navigate(Third)
                    }
                )
            }
            // ...
        }
    }

  9. همه Fragmentها، طرح‌بندی‌های XML مربوطه، پیمایش غیرضروری و سایر منابع، و وابستگی‌های Fragment و Jetpack Navigation قدیمی را بردارید.

می‌توانید همین مراحل را با جزئیات بیشتر مربوط به Navigation Compose در اسناد راه‌اندازی پیدا کنید.

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

مهم نیست از کدام مؤلفه «پیمایش» استفاده می‌کنید، همان اصول پیمایش اعمال می‌شود.

موارد استفاده رایج هنگام انتقال شامل موارد زیر است:

برای اطلاعات دقیق‌تر درباره این موارد استفاده، به پیمایش با Compose مراجعه کنید.

بازیابی داده‌های پیچیده هنگام پیمایش

اکیداً توصیه می‌کنیم هنگام پیمایش، اشیای داده پیچیده را منتقل نکنید. به‌جای آن، اطلاعات ضروری حداقلی، مثل شناسه یکتا یا فرم دیگری از شناسه را به‌عنوان آرگومان هنگام انجام کنش‌های پیمایش ارسال کنید. باید اشیاء پیچیده را به‌عنوان داده در یک منبع واحد حقیقت، مانند لایه داده، ذخیره کنید. برای اطلاعات بیشتر، بازیابی داده‌های پیچیده هنگام ناوبری را ببینید.

اگر «قطعه‌های» شما اشیای پیچیده را به‌عنوان آرگومان ارسال می‌کنند، ابتدا کدتان را به‌گونه‌ای بازسازی کنید که امکان ذخیره و واکشی این اشیا از لایه داده فراهم شود. برای مشاهده نمونه‌ها، به مخزن «اکنون در Android» مراجعه کنید.

محدودیت‌ها

این بخش محدودیت‌های فعلی Navigation Compose را شرح می‌دهد.

انتقال افزایشی به Navigation Compose

درحال‌حاضر، نمی‌توانید از Navigation Compose استفاده کنید درحالی‌که هنوز از Fragments به‌عنوان مقصد در کدتان استفاده می‌کنید. برای شروع استفاده از Navigation Compose، همه مقصدهای شما باید composable باشند. می‌توانید این درخواست ویژگی را در Issue Tracker پیگیری کنید.

پویانمایی‌های گذار

از Navigation 2.7.0-alpha01، پشتیبانی از تنظیم انتقال‌های سفارشی، که قبلاً از AnimatedNavHost بود، اکنون مستقیماً در NavHost پشتیبانی می‌شود. برای اطلاعات بیشتر، یادداشت‌های انتشار را بخوانید.

بیشتر بدانید

برای اطلاعات بیشتر درباره انتقال به Navigation Compose، منابع زیر را ببینید:

  • ‫Navigation Compose codelab: با اصول اولیه Navigation Compose در codelab عملی آشنا شوید.
  • مخزن Now in Android: یک برنامه Android کاملاً کاربردی که کاملاً با Kotlin و Jetpack Compose ساخته شده است، از بهترین روش‌های طراحی و توسعه Android پیروی می‌کند، و شامل Navigation Compose است.
  • انتقال Sunflower به Jetpack Compose: پست وبلاگی که مسیر انتقال برنامه نمونه Sunflower از Views به Compose را مستند می‌کند، که شامل انتقال به Navigation Compose نیز می‌شود.
  • Jetnews برای هر صفحه‌نمایش: پست وبلاگی که بازسازی کد و انتقال نمونه Jetnews را برای پشتیبانی از همه صفحه‌نمایش‌ها با Jetpack Compose و Navigation Compose مستند می‌کند.