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، این مراحل را دنبال کنید:
- وابستگی Navigation Compose را به برنامه خود اضافه کنید.
یک کامپوننت
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(/* ... */) } } }
برای هر مقصد ناوبری، انواعی ایجاد کنید. برای مقاصدی که به هیچ دادهای نیاز ندارند، از یک
data object
و برای مقاصدی که به داده نیاز دارند،data class
یاclass
استفاده کنید.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
NavController
در مکانی تنظیم کنید که تمام composableهایی که نیاز به ارجاع به آن دارند، به آن دسترسی داشته باشند (این معمولاً درونApp
composable شماست). این رویکرد از اصول بالا بردن وضعیت (state hoisting) پیروی میکند و به شما امکان میدهد ازNavController
به عنوان منبع حقیقت برای پیمایش بین صفحات composable و حفظ back stack استفاده کنید:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
NavHost
برنامه خود را درونApp
composable ایجاد کنید وnavController
به آن ارسال کنید:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
مقاصد
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(/* ... */) } // ... } }
اگر از راهنماییهای مربوط به معماری رابط کاربری Compose خود ، به ویژه نحوهی ارسال
ViewModel
ها و رویدادهای ناوبری به composableها، پیروی کرده باشید، مرحلهی بعدی تغییر نحوهی ارائهیViewModel
به هر صفحهی composable است. اغلب میتوانید از Hilt injection و نقطهی ادغام آن با Compose و Navigation از طریقhiltViewModel
استفاده کنید:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
تمام فراخوانیهای ناوبری
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) } ) } // ... } }
تمام 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 مستند میکند.
برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- پیمایش با Compose
- نوشتن و کتابخانههای دیگر
- ملاحظات دیگر