تتيح لك واجهة برمجة التطبيقات Navigation Compose التنقّل بين العناصر القابلة للإنشاء في تطبيق Compose، مع الاستفادة من مكوِّن Jetpack Navigation والبنية الأساسية والميزات.
توضّح هذه الصفحة كيفية نقل البيانات من Jetpack Navigation المستند إلى Fragment إلى Navigation Compose، وذلك كجزء من عملية نقل أكبر لواجهة المستخدم المستندة إلى View إلى Jetpack Compose.
المتطلبات الأساسية لعملية نقل البيانات
يمكنك الانتقال إلى Navigation Compose بعد أن تتمكّن من استبدال جميع Fragments بعناصر واجهة المستخدم القابلة للإنشاء للشاشة المقابلة. يمكن أن تحتوي العناصر القابلة للإنشاء على الشاشة على مزيج من محتوى Compose وView، ولكن يجب أن تكون جميع وجهات التنقّل عبارة عن عناصر قابلة للإنشاء لتفعيل عملية نقل البيانات إلى Navigation Compose. وحتى ذلك الحين، عليك مواصلة استخدام مكوّن التنقّل المستند إلى الأجزاء في قاعدة الرموز البرمجية المتوافقة مع View وCompose. لمزيد من المعلومات، يمكنك الاطّلاع على مستندات التوافق التشغيلي الخاصة بالتنقّل.
لا يُشترط استخدام Navigation Compose في تطبيق يعتمد على Compose فقط. يمكنك مواصلة استخدام مكوّن التنقّل المستند إلى Fragment، طالما أنّك تحتفظ بـ Fragments لاستضافة المحتوى القابل للإنشاء.
خطوات نقل البيانات
سواء كنت تتّبع استراتيجية النقل المقترَحة أو تتّخذ نهجًا آخر، ستصل إلى مرحلة تكون فيها جميع وجهات التنقّل عبارة عن عناصر واجهة مستخدم قابلة للإنشاء، وتعمل الفئات Fragment كحاويات قابلة للإنشاء فقط. في هذه المرحلة، يمكنك الانتقال إلى Navigation Compose.
إذا كان تطبيقك يتّبع نمط تصميم لوظائف المستخدم المحدّدة ودليلنا حول البنية، لن يتطلّب نقل التطبيق إلى Jetpack Compose وNavigation Compose إعادة تصميم كبيرة للطبقات الأخرى في تطبيقك، باستثناء طبقة واجهة المستخدم.
للانتقال إلى Navigation Compose، اتّبِع الخطوات التالية:
- أضِف التبعية الخاصة بمكتبة Navigation Compose إلى تطبيقك.
أنشئ عنصر
App-levelقابل للإنشاء وأضِفه إلىActivityكنقطة دخول إلى Compose، مع استبدال عملية إعداد تخطيط 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في مكان يمكن لجميع العناصر القابلة للإنشاء التي تحتاج إلى الرجوع إليه الوصول إليه (يكون ذلك عادةً داخل العنصر القابل للإنشاءApp). يتّبع هذا الأسلوب مبادئ نقل الحالة للأعلى ويتيح لك استخدامNavControllerكمصدر موثوق للتنقّل بين الشاشات القابلة للإنشاء والحفاظ على سجلّ الرجوع:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
أنشئ
NavHostتطبيقك داخل العنصر القابل للإنشاءAppومرِّرnavController:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
أضِف وجهات
composableلإنشاء الرسم البياني للتنقّل. إذا سبق أن تم نقل كل شاشة إلى Compose، ستتضمّن هذه الخطوة استخراج عناصر Compose الخاصة بالشاشة من الفئات 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(/* ... */) } // ... } }
إذا اتّبعت الإرشادات الواردة في تصميم واجهة المستخدم المستندة إلى Compose، خاصةً كيفية تمرير
ViewModels وأحداث التنقّل إلى عناصر قابلة للإنشاء، تكون الخطوة التالية هي تغيير طريقة توفيرViewModelلكل عنصر قابل للإنشاء خاص بالشاشة. يمكنك غالبًا استخدام ميزة "إدخال التبعية" في Hilt ونقطة الدمج مع 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) } ) } // ... } }
أزِل جميع الفئات Fragments وتنسيقات XML ذات الصلة وعناصر التنقّل غير الضرورية والموارد الأخرى، بالإضافة إلى الفئات Fragments القديمة وتبعيات Jetpack Navigation.
يمكنك العثور على الخطوات نفسها مع المزيد من التفاصيل المتعلّقة بمكتبة Navigation Compose في مستندات الإعداد.
حالات الاستخدام الشائعة
بغض النظر عن مكوّن التنقّل الذي تستخدمه، تنطبق مبادئ التنقّل نفسها.
تشمل حالات الاستخدام الشائعة عند نقل البيانات ما يلي:
- الانتقال إلى عنصر قابل للإنشاء
- التنقّل باستخدام الوسيطات
- الروابط لصفحات في التطبيق
- التنقل المتداخل
- التكامل مع شريط التنقّل السفلي
- الدمج مع مكوّن تنقّل مخصّص
لمزيد من المعلومات التفصيلية حول حالات الاستخدام هذه، يمكنك الاطّلاع على التنقّل باستخدام Compose.
استرداد بيانات معقّدة أثناء التنقّل
ننصح بشدة بعدم تمرير عناصر بيانات معقّدة عند التنقّل. بدلاً من ذلك، مرِّر الحد الأدنى من المعلومات الضرورية، مثل معرّف فريد أو أي شكل آخر من أشكال التعريف، كوسيطات عند تنفيذ إجراءات التنقّل. يجب تخزين العناصر المعقّدة كبيانات في مصدر واحد للحقيقة، مثل طبقة البيانات. لمزيد من المعلومات، يُرجى الاطّلاع على استرداد البيانات المعقّدة عند التنقّل.
إذا كانت الفئات Fragment تمرّر عناصر معقّدة كمعلَمات، ننصحك بإعادة تصميم الرمز البرمجي أولاً بطريقة تتيح تخزين هذه العناصر واسترجاعها من طبقة البيانات. يمكنك الاطّلاع على مستودع Now in Android للحصول على أمثلة.
القيود
يوضّح هذا القسم القيود الحالية على Navigation Compose.
النقل التدريجي إلى Navigation Compose
في الوقت الحالي، لا يمكنك استخدام Navigation Compose مع الاستمرار في استخدام Fragments كوجهات في الرمز البرمجي. لبدء استخدام Navigation Compose، يجب أن تكون جميع وجهاتك قابلة للإنشاء. يمكنك تتبُّع طلب الميزة هذا على Issue Tracker.
الصور المتحركة للانتقال
بدءًا من Navigation 2.7.0-alpha01، أصبح بإمكانك ضبط انتقالات مخصّصة مباشرةً في NavHost، بعد أن كان ذلك متاحًا سابقًا من خلال AnimatedNavHost. يمكنك الاطّلاع على ملاحظات الإصدار للحصول على مزيد من المعلومات.
مزيد من المعلومات
لمزيد من المعلومات حول نقل البيانات إلى Navigation Compose، يُرجى الاطّلاع على المراجع التالية:
- الدرس التطبيقي حول الترميز في Navigation Compose: تعرَّف على أساسيات Navigation Compose من خلال درس تطبيقي حول الترميز.
- مستودع Now in Android: تطبيق Android يعمل بكامل طاقته تم إنشاؤه بالكامل باستخدام Kotlin وJetpack Compose، ويتّبع أفضل الممارسات في تصميم وتطوير تطبيقات Android ويتضمّن Navigation Compose.
- نقل بيانات تطبيق Sunflower إلى Jetpack Compose: مشاركة مدوّنة توثّق رحلة نقل بيانات تطبيق Sunflower النموذجي من Views إلى Compose، وتشمل أيضًا نقل البيانات إلى Navigation Compose.
- تطبيق Jetnews على كل شاشة: مشاركة مدوّنة توثّق عملية إعادة تصميم ونقل نموذج تطبيق Jetnews ليتوافق مع جميع الشاشات باستخدام Jetpack Compose وNavigation Compose.
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون JavaScript غير مفعّلة
- التنقّل باستخدام Compose
- Compose والمكتبات الأخرى
- اعتبارات أخرى