يمكنك إضافة واجهة مستخدم مستندة إلى Compose إلى تطبيق حالي يستخدم تصميمًا مستندًا إلى View.
لإنشاء شاشة جديدة بالكامل تستند إلى 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،
من Composition عند فصل
ComposeView
عن النافذة، ما لم يكن جزءًا من حاوية تجميع مثل
RecyclerView. في تطبيق يتضمّن نشاطًا واحدًا يعتمد على Compose فقط، يكون هذا السلوك التلقائي هو المطلوب، ولكن إذا كنت تضيف Compose بشكل تدريجي إلى قاعدة الرموز البرمجية، قد يتسبّب هذا السلوك في فقدان الحالة في بعض السيناريوهات.
لتغيير ViewCompositionStrategy، استخدِم طريقة setViewCompositionStrategy()
وقدِّم استراتيجية مختلفة.
يلخّص الجدول أدناه السيناريوهات المختلفة التي يمكنك استخدام ViewCompositionStrategy فيها:
ViewCompositionStrategy |
الوصف وسيناريو التشغيل التفاعلي |
|---|---|
DisposeOnDetachedFromWindow |
سيتم إيقاف Composition نهائيًا عند فصل ComposeView الأساسي عن النافذة. تم استبدالها منذ ذلك الحين بـ DisposeOnDetachedFromWindowOrReleasedFromPool.سيناريو التشغيل التفاعلي: * ComposeView سواء كان العنصر الوحيد في هيكل طرق العرض أو في سياق شاشة مختلطة من View/Compose (ليس في Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (تلقائي) |
على غرار DisposeOnDetachedFromWindow، عندما لا يكون العمل الموسيقي في حاوية تجميع، مثل RecyclerView إذا كان في حاوية تجميع، سيتم التخلص منه عندما تنفصل حاوية التجميع نفسها عن النافذة، أو عندما يتم تجاهل العنصر (أي عندما تكون المجموعة ممتلئة).سيناريو التشغيل التفاعلي: * ComposeView سواء كان العنصر الوحيد في هيكلية طرق العرض، أو في سياق شاشة مختلطة من طرق العرض/Compose (ليس في Fragment).* ComposeView كعنصر في حاوية تجميع، مثل RecyclerView |
DisposeOnLifecycleDestroyed |
سيتم إيقاف Composition نهائيًا عند إيقاف Lifecycle المقدَّم نهائيًا.سيناريو التشغيل التفاعلي * ComposeView في "طريقة العرض" الخاصة بـ Fragment |
DisposeOnViewTreeLifecycleDestroyed |
سيتم التخلص من Composition عندما يتم إتلاف Lifecycle الذي يملكه LifecycleOwner الذي تم إرجاعه بواسطة ViewTreeLifecycleOwner.get من النافذة التالية التي تم ربط العرض بها.سيناريو التشغيل التفاعلي: * ComposeView في "عرض" ضمن "جزء".* ComposeView في طريقة عرض لم يتم تحديد حالة دورة الحياة فيها بعد |
ComposeView في "الحطام" (خطوة انتقالية)
إذا أردت دمج محتوى واجهة مستخدم Compose في جزء أو تخطيط View حالي، استخدِم 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، واضبط استراتيجية Composition التي تناسب
المضيف 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 } }
بدلاً من ذلك، يمكنك أيضًا استخدام View Binding للحصول على مراجع إلى
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. يتم عرض النص "Hello 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 tools واضبط قيمتها على الاسم المؤهَّل بالكامل للدالة المركّبة التي تريد معاينتها في التصميم.
<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>
