كتابة الأمان في Kotlin DSL والتنقل Compose

يمكنك استخدام واجهات برمجة تطبيقات مدمجة وآمنة من حيث الأنواع لتوفير منع أخطاء الكتابة في وقت التجميع لـ مخطط التنقّل. تتوفّر واجهات برمجة التطبيقات هذه عندما يستخدم تطبيقك Navigation Compose أو Navigation Kotlin DSL. وهي متاحة اعتبارًا من ‎Navigation 2.8.0.

تتطابق وظائف واجهات برمجة التطبيقات هذه مع وظائف Safe Args التي توفّرها لرسومات التنقّل التي تم إنشاؤها باستخدام XML.

تحديد المسارات

لاستخدام مسارات آمنة من حيث النوع في Compose، عليك أولاً تحديد فئات أو عناصر قابلة للتسلسل تمثّل مساراتك.

لتحديد الكائنات القابلة للتسلسل، استخدِم التعليق التوضيحي @Serializable الذي يوفّره المكوّن الإضافي Kotlin Serialization. يمكن إضافة هذه المكوّن الإضافي إلى مشروعك من خلال إضافة هذه التبعيات.

استخدِم القواعد التالية لتحديد نوع المسار الذي تريد استخدامه:

  • الكائن: استخدِم كائنًا للمسارات بدون وسيطات.
  • الفئة: استخدِم فئة أو فئة بيانات للمسارات التي تتضمّن وسيطات.
  • KClass<T>: استخدِم هذه السمة إذا لم تكن بحاجة إلى تمرير وسيطات، مثل فئة بدون مَعلمات أو فئة تتضمّن مَعلمات لها قيم تلقائية
    1. على سبيل المثال: Profile::class

في جميع الحالات، يجب أن يكون العنصر أو الفئة قابلاً للتسلسل.

على سبيل المثال:

// Define a home route that doesn't take any arguments
@Serializable
object Home

// Define a profile route that takes an ID
@Serializable
data class Profile(val id: String)

إنشاء الرسم البياني

بعد ذلك، عليك تحديد الرسم البياني للتنقّل. استخدِم الدالة composable() لتحديد العناصر القابلة للإنشاء كوجهات في الرسم البياني للتنقّل.

NavHost(navController, startDestination = Home) {
     composable<Home> {
         HomeScreen(onNavigateToProfile = { id ->
             navController.navigate(Profile(id))
         })
     }
     composable<Profile> { backStackEntry ->
         val profile: Profile = backStackEntry.toRoute()
         ProfileScreen(profile.id)
     }
}

لاحظ ما يلي في هذا المثال:

  • تتضمّن composable() مَعلمة نوع. أي composable<Profile>.
  • يُعدّ تحديد نوع الوجهة أسلوبًا أكثر فعالية من تمرير route سلسلة كما هو الحال في composable("profile").
  • يحدّد فئة المسار نوع كل وسيط تنقّل، كما هو الحال في val id: String، لذلك لا حاجة إلى NavArgument.
  • بالنسبة إلى مسار الملف الشخصي، يعيد الإجراء toRoute() إنشاء الكائن Profile من NavBackStackEntry ومَعلماته.

لمزيد من المعلومات حول كيفية تصميم الرسم البياني بشكل عام، يُرجى الاطّلاع على صفحة تصميم الرسم البياني للتنقّل.

الوصول إلى الوسيطات في ViewModel

للوصول إلى الوسيطات من مسار آمن من حيث النوع في ViewModel، يمكنك استرداد المسار من SavedStateHandle من خلال استدعاء SavedStateHandle.toRoute<T>()، حيث T هو فئة المسار:

class ProfileViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    private val profile = savedStateHandle.toRoute<Profile>()
    private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)
}

أخيرًا، يمكنك الانتقال إلى الدالة المركّبة باستخدام الدالة navigate() من خلال تمرير مثيل المسار:

navController.navigate(Profile(id = 123))

ينقل ذلك المستخدم إلى الوجهة composable<Profile> في الرسم البياني للتنقّل. يمكن الحصول على أي وسيطات تنقّل، مثل id، من خلال إعادة إنشاء Profile باستخدام NavBackStackEntry.toRoute وقراءة خصائصه.

مراجع إضافية