تتيح لك واجهة برمجة التطبيقات Navigation Compose التنقّل بين العناصر القابلة للإنشاء في تطبيق Compose، مع الاستفادة من مكوِّن Jetpack Navigation والبنية الأساسية والميزات.
توضّح هذه الصفحة كيفية نقل البيانات من Jetpack Navigation المستند إلى Fragment إلى Navigation Compose، وذلك كجزء من عملية نقل أكبر لواجهة المستخدم المستندة إلى View إلى Jetpack Compose.
المتطلبات الأساسية لعملية نقل البيانات
يمكنك الانتقال إلى Navigation Compose بعد أن تتمكّن من استبدال جميع Fragments بعناصر واجهة المستخدم القابلة للإنشاء للشاشة المقابلة. يمكن أن تحتوي العناصر القابلة للإنشاء على الشاشة على مزيج من محتوى Compose وView، ولكن يجب أن تكون جميع وجهات التنقّل عناصر قابلة للإنشاء لتفعيل عملية نقل البيانات إلى Navigation Compose. وحتى ذلك الحين، عليك مواصلة استخدام مكوّن التنقّل المستند إلى Fragment في قاعدة الرموز البرمجية المتوافقة مع View وCompose. يمكنك الاطّلاع على مستندات التوافق التشغيلي الخاصة بالتنقّل لمزيد من المعلومات.
لا يُشترط استخدام Navigation Compose في تطبيق يعتمد على Compose فقط. يمكنك مواصلة استخدام مكوّن التنقّل المستند إلى Fragment، طالما أنّك تحتفظ بـ Fragments لاستضافة المحتوى القابل للإنشاء.
خطوات نقل البيانات
سواء كنت تتّبع استراتيجية النقل المقترَحة أو تتّخذ نهجًا آخر، ستصل إلى مرحلة تكون فيها جميع وجهات التنقّل عبارة عن عناصر واجهة مستخدم قابلة للإنشاء، وتعمل الفئات Fragment كحاويات فقط للعناصر القابلة للإنشاء. في هذه المرحلة، يمكنك الانتقال إلى Navigation Compose.
إذا كان تطبيقك يتّبع حاليًا نمط تصميم لوظائف المستخدم المحدّدة ودليلنا حول البنية، لن يتطلّب نقل التطبيق إلى Jetpack Compose وNavigation Compose إجراء عمليات إعادة تصميم كبيرة في طبقات تطبيقك الأخرى، باستثناء طبقة واجهة المستخدم.
للانتقال إلى Navigation Compose، اتّبِع الخطوات التالية:
- أضِف Navigation Compose dependency إلى تطبيقك.
أنشئ عنصر
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 الخاصة بالشاشة من "التقسيمات" إلى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
s وأحداث التنقّل إلى عناصر قابلة للإنشاء، تكون الخطوة التالية هي تغيير طريقة توفير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) } ) } // ... } }
أزِل جميع الفئات Fragment وتنسيقات XML ذات الصلة وعناصر التنقّل غير الضرورية والموارد الأخرى، بالإضافة إلى الفئات Fragment القديمة وتبعيات Jetpack Navigation.
يمكنك العثور على الخطوات نفسها مع المزيد من التفاصيل المتعلّقة بمكتبة Navigation Compose في مستندات الإعداد.
حالات الاستخدام الشائعة
بغض النظر عن مكوّن التنقّل الذي تستخدمه، تنطبق مبادئ التنقّل نفسها.
تشمل حالات الاستخدام الشائعة عند نقل البيانات ما يلي:
- الانتقال إلى عنصر قابل للإنشاء
- التنقّل باستخدام الوسيطات
- الروابط لصفحات في التطبيق
- التنقل المتداخل
- التكامل مع شريط التنقّل السفلي
- الدمج مع مكوّن تنقّل مخصّص
لمزيد من المعلومات التفصيلية حول حالات الاستخدام هذه، يمكنك الاطّلاع على التنقّل باستخدام Compose.
استرداد بيانات معقّدة أثناء التنقّل
ننصح بشدة بعدم تمرير عناصر بيانات معقّدة عند التنقّل. بدلاً من ذلك، مرِّر الحد الأدنى من المعلومات الضرورية، مثل معرّف فريد أو أي شكل آخر من أشكال التعريف، كمعلَمات عند تنفيذ إجراءات التنقّل. يجب تخزين العناصر المعقّدة كبيانات في مصدر واحد للحقيقة، مثل طبقة البيانات. لمزيد من المعلومات، يُرجى الاطّلاع على استرداد البيانات المعقّدة عند التنقّل.
إذا كانت الفئات Fragments تمرّر عناصر معقّدة كمعلَمات، ننصحك بإعادة تصميم الرمز البرمجي أولاً بطريقة تتيح تخزين هذه العناصر واسترجاعها من طبقة البيانات. يمكنك الاطّلاع على مستودع Now in Android للحصول على أمثلة.
القيود
يوضّح هذا القسم القيود الحالية على Navigation Compose.
النقل التدريجي إلى Navigation Compose
في الوقت الحالي، لا يمكنك استخدام Navigation Compose مع الاستمرار في استخدام "التقسيمات" كوجهات في الرمز البرمجي. لبدء استخدام 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 والمكتبات الأخرى
- اعتبارات أخرى