Jetpack Navigation را به Navigation Compose منتقل کنید

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

این صفحه نحوه مهاجرت از Jetpack Navigation مبتنی بر Fragment به Navigation Compose را به عنوان بخشی از مهاجرت بزرگتر رابط کاربری مبتنی بر View به Jetpack Compose شرح می‌دهد.

پیش‌نیازهای مهاجرت

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

استفاده از Navigation Compose در یک برنامه فقط-کامپوزیت (Compose-only) پیش‌نیاز نیست. می‌توانید به استفاده از کامپوننت Navigation مبتنی بر Fragment ادامه دهید ، البته تا زمانی که Fragments را برای میزبانی محتوای قابل ترکیب خود نگه دارید.

مراحل مهاجرت

چه از استراتژی مهاجرت پیشنهادی ما پیروی کنید و چه رویکرد دیگری را در پیش بگیرید، به نقطه‌ای خواهید رسید که تمام مقاصد ناوبری، صفحه‌های قابل ترکیب هستند و Fragments فقط به عنوان کانتینرهای قابل ترکیب عمل می‌کنند. در این مرحله، می‌توانید به 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 در مکانی تنظیم کنید که تمام composableهایی که نیاز به ارجاع به آن دارند، به آن دسترسی داشته باشند (این معمولاً درون App composable شماست). این رویکرد از اصول بالا بردن وضعیت (state hoisting) پیروی می‌کند و به شما امکان می‌دهد از NavController به عنوان منبع حقیقت برای پیمایش بین صفحات composable و حفظ back stack استفاده کنید:

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

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

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

  6. مقاصد composable را برای ساخت نمودار ناوبری خود اضافه کنید. اگر هر صفحه قبلاً به Compose منتقل شده باشد، این مرحله فقط شامل استخراج این Composableهای صفحه از Fragments شما به مقاصد 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 ها و رویدادهای ناوبری به composableها، پیروی کرده باشید، مرحله‌ی بعدی تغییر نحوه‌ی ارائه‌ی ViewModel به هر صفحه‌ی composable است. اغلب می‌توانید از Hilt injection و نقطه‌ی ادغام آن با 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 در مستندات Setup بیابید.

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

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

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

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

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

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

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

محدودیت‌ها

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

مهاجرت افزایشی به ناوبری Compose

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

انیمیشن‌های گذار

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

بیشتر بدانید

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

  • آزمایشگاه کدنویسی Navigation Compose : اصول اولیه Navigation Compose را با یک آزمایشگاه کد عملی بیاموزید.
  • اکنون در مخزن اندروید : یک برنامه اندروید کاملاً کاربردی که کاملاً با Kotlin و Jetpack Compose ساخته شده است، که از بهترین شیوه‌های طراحی و توسعه اندروید پیروی می‌کند و شامل Navigation Compose نیز می‌شود.
  • مهاجرت از Sunflower به Jetpack Compose : یک پست وبلاگ که روند مهاجرت برنامه نمونه Sunflower از Views به Compose را مستند می‌کند، که شامل مهاجرت به Navigation Compose نیز می‌شود.
  • Jetnews برای هر صفحه نمایش : یک پست وبلاگ که بازسازی و مهاجرت نمونه Jetnews را برای پشتیبانی از همه صفحه نمایش‌ها با Jetpack Compose و Navigation Compose مستند می‌کند.
{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}