يمكنك إضافة واجهة مستخدم مستندة إلى Compose إلى تطبيق حالي يستخدم تصميمًا مستندًا إلى العرض.
لإنشاء شاشة جديدة مستندة بالكامل إلى Compose، يمكنك جعل نشاطك يستدعي طريقة setContent() وتمرير أي دوال مركّبة تريدها.
class ExampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // In here, we can call composables! MaterialTheme { Greeting(name = "compose") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
يشبه هذا الرمز ما ستجده في تطبيق يستخدم Compose فقط.
ViewCompositionStrategy لمدة ComposeView
يحدّد ViewCompositionStrategy وقت التخلص من Composition. تتخلص الاستراتيجية التلقائية
ViewCompositionStrategy.Default
من التركيبة عندما يتم فصل
ComposeView
الأساسية عن النافذة، ما لم تكن جزءًا من حاوية تجميع مثل
RecyclerView. في تطبيق Compose-only الذي يتضمّن نشاطًا واحدًا، يكون هذا الإعداد التلقائي هو
ما تريده، ولكن إذا كنت تضيف Compose بشكل تدريجي في
قاعدة الرموز البرمجية، قد يؤدي هذا السلوك إلى فقدان الحالة في بعض السيناريوهات.
لتغيير ViewCompositionStrategy، استخدِم طريقة setViewCompositionStrategy()
وقدِّم استراتيجية مختلفة.
يلخّص الجدول أدناه السيناريوهات المختلفة التي يمكنك استخدام ViewCompositionStrategy فيها:
ViewCompositionStrategy |
الوصف وسيناريو التشغيل التفاعلي |
|---|---|
DisposeOnDetachedFromWindow |
سيتم التخلص من Composition عندما يتم فصل ComposeView الأساسي عن النافذة. وقد حلّ محلّه DisposeOnDetachedFromWindowOrReleasedFromPool.سيناريو التشغيل التفاعلي: * ComposeView سواء كان العنصر الوحيد في هيكلية طرق العرض أو في سياق شاشة مختلطة بين طرق العرض وCompose (وليس في Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (تلقائي) |
على غرار DisposeOnDetachedFromWindow، عندما لا يكون Composition في حاوية تجميع، مثل RecyclerView. إذا كان العنصر في حاوية تجميع، سيتم التخلص منه عندما تنفصل حاوية التجميع نفسها عن النافذة أو عندما يتم تجاهل العنصر (أي عندما تكون المجموعة ممتلئة).سيناريو التشغيل التفاعلي: * ComposeView سواء كان العنصر الوحيد في هيكلية طرق العرض أو في سياق شاشة مختلطة بين View وCompose (ليس في Fragment).* ComposeView كسلعة في حاوية تجميع مثل RecyclerView |
DisposeOnLifecycleDestroyed |
سيتم التخلص من Composition عند تدمير Lifecycle المقدَّم.سيناريو التشغيل التفاعلي * ComposeView في عرض Fragment. |
DisposeOnViewTreeLifecycleDestroyed |
سيتم التخلص من Composition عندما يتم تدمير Lifecycle المملوك من قِبل LifecycleOwner الذي تم إرجاعه من قِبل ViewTreeLifecycleOwner.get للنافذة التالية التي تم إرفاق View بها.سيناريو Interop: * ComposeView في View الخاص بـ Fragment.* ComposeView في طريقة عرض لا تزال فيها مراحل النشاط غير معروفة |
ComposeView في "الأجزاء" (خطوة انتقالية)
إذا أردت دمج محتوى واجهة مستخدم Compose في جزء أو تنسيق عرض حالي، استخدِم ComposeView واستدعِ طريقة setContent(). ComposeView هو View على Android.
يمكنك وضع ComposeView في تنسيق XML مثل أي View آخر:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
في الرمز المصدر لـ Kotlin، يمكنك توسيع التصميم من مورد التصميم المحدّد في ملف XML. بعد ذلك، يمكنك الحصول على
ComposeView باستخدام معرّف XML، وضبط استراتيجية "الإنشاء" التي تناسب
المضيف View، واستدعاء setContent() لاستخدام Compose.
class ExampleFragmentXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.fragment_example, container, false) val composeView = view.findViewById<ComposeView>(R.id.compose_view) composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } }
بدلاً من ذلك، يمكنك أيضًا استخدام ربط الملفات الشخصية للحصول على مراجع
ComposeView من خلال الإشارة إلى فئة الربط التي تم إنشاؤها لملف تنسيق XML:
class ExampleFragment : Fragment() { private var _binding: FragmentExampleBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentExampleBinding.inflate(inflater, container, false) val view = binding.root binding.composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } override fun onDestroyView() { super.onDestroyView() _binding = null } }
الشكل 1: يعرض هذا الناتج من الرمز الذي يضيف عناصر Compose في التسلسل الهرمي لواجهة مستخدم View. يتم عرض النص "مرحبًا Android!" من خلال تطبيق مصغّر TextView. يتم عرض النص "Hello Compose!" من خلال عنصر نصي في Compose.
يمكنك أيضًا تضمين ComposeView مباشرةً في جزء إذا كانت شاشة ملء الشاشة
مصمَّمة باستخدام Compose، ما يتيح لك تجنُّب استخدام ملف تنسيق XML بالكامل.
class ExampleFragmentNoXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { MaterialTheme { // In Compose world Text("Hello Compose!") } } } } }
مثيلات متعددة من ComposeView في التنسيق نفسه
إذا كانت هناك عناصر ComposeView متعددة في التنسيق نفسه، يجب أن يكون لكل عنصر معرّف فريد لكي يعمل savedInstanceState.
class ExampleFragmentMultipleComposeView : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = LinearLayout(requireContext()).apply { addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_x // ... } ) addView(TextView(requireContext())) addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_y // ... } ) } }
يتم تحديد معرّفات ComposeView في ملف res/values/ids.xml:
<resources> <item name="compose_view_x" type="id" /> <item name="compose_view_y" type="id" /> </resources>
معاينة الدوال المركّبة في "محرِّر التنسيق"
يمكنك أيضًا معاينة الدوال المركّبة ضمن "محرِّر التنسيق" لتنسيق XML الذي يحتوي على ComposeView. يتيح لك ذلك الاطّلاع على شكل الدوال المركّبة
ضمن تنسيق مختلط بين "طرق العرض" وCompose.
لنفترض أنّك تريد عرض الدالة المركّبة التالية في "محرّر التنسيق". يُرجى العِلم أنّ الدوال المركّبة التي تم وضع تعليقات توضيحية عليها باستخدام @Preview هي خيارات جيدة للمعاينة في "محرِّر التنسيق".
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
لعرض هذه الدالة المركّبة، استخدِم سمة الأدوات tools:composableName واضبط قيمتها على الاسم المؤهَّل بالكامل للدالة المركّبة المطلوب معاينتها في التنسيق.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.compose.ui.platform.ComposeView android:id="@+id/my_compose_view" tools:composableName="com.example.compose.snippets.interop.InteroperabilityAPIsSnippetsKt.GreetingPreview" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout>
