يمكنك تضمين تسلسل هرمي لعرض Android في واجهة مستخدم Compose. يكون هذا النهج مفعّلاً بشكلٍ خاص إذا كنت تريد استخدام عناصر واجهة مستخدِم غير متاحة بعد في ميزة
الإنشاء، مثل
AdView
.
يتيح لك هذا الأسلوب أيضًا إعادة استخدام الاطِّلاعات المخصّصة التي ربما تكون قد صمّمتها.
لتضمين عنصر عرض أو تسلسل هرمي، استخدِم العنصر AndroidView
composable. يتم تمرير دالة LAMBDA إلى AndroidView
لعرض
View
. يوفّر AndroidView
أيضًا دالة update
ردّ اتصال يتمّ استدعاؤها عند تضخيم طريقة العرض. تتم إعادة تركيب AndroidView
كلما تغيّر State
الذي تم قراءته في ردّ الاتصال. يأخذ العنصر AndroidView
، مثل العديد من العناصر القابلة للتجميع المضمّنة الأخرى، مَعلمة Modifier
التي يمكن استخدامها، مثلاً، لضبط موضعه في العنصر القابل للتجميع الرئيسي.
@Composable fun CustomView() { var selectedItem by remember { mutableStateOf(0) } // Adds view to Compose AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> // Creates view MyView(context).apply { // Sets up listeners for View -> Compose communication setOnClickListener { selectedItem = 1 } } }, update = { view -> // View's been inflated or state read in this block has been updated // Add logic here if necessary // As selectedItem is read here, AndroidView will recompose // whenever the state changes // Example of Compose -> View communication view.selectedItem = selectedItem } ) } @Composable fun ContentExample() { Column(Modifier.fillMaxSize()) { Text("Look at this CustomView!") CustomView() } }
AndroidView
مع ربط طريقة العرض
لتضمين تنسيق XML، استخدِم واجهة برمجة التطبيقات
AndroidViewBinding
، التي تقدّمها مكتبة androidx.compose.ui:ui-viewbinding
. للقيام بذلك، يجب أن يفعّل مشروعك ربط العرض.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView
في القوائم البطيئة
إذا كنت تستخدم AndroidView
في قائمة بطيئة التحميل (LazyColumn
أو LazyRow
أو
Pager
أو غير ذلك)، ننصحك باستخدام طريقة التحميل الزائد AndroidView
التي تم تقديمها في الإصدار 1.4.0-rc01. تسمح هذه التحميلات الزائدة لـ Compose بإعادة استخدام
مثيل View
الأساسي عند إعادة استخدام التركيب المُحتوي كما هو الحال في
القوائم البطيئة.
تضيف هذه الوظيفة الزائدة لـ AndroidView
مَعلمتَين إضافيتين:
onReset
: دالة يتمّ استدعاؤها للإشارة إلى أنّه سيتم إعادة استخدامView
. يجب أن يكون هذا الحقل غير فارغ لتفعيل إعادة استخدام "العرض".-
onRelease
(اختياري) - دالة استدعاء يتمّ استدعاؤها للإشارة إلى أنّView
قد خرج من المكوّن ولن تتم إعادة استخدامه مرة أخرى.
@OptIn(ExperimentalComposeUiApi::class) @Composable fun AndroidViewInLazyList() { LazyColumn { items(100) { index -> AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> MyView(context) }, update = { view -> view.selectedItem = index }, onReset = { view -> view.clear() } ) } } }
الأجزاء في ميزة "الإنشاء"
استخدِم العنصر القابل للتجميع AndroidViewBinding
لإضافة Fragment
في ميزة "الإنشاء".
تتضمّن AndroidViewBinding
معالجة خاصة بالشريحة، مثل إزالة
الشريحة عندما يغادر العنصر القابل للتجميع التركيب.
يمكنك إجراء ذلك من خلال توسيع ملف XML يحتوي على FragmentContainerView
كحامل لملف Fragment
.
على سبيل المثال، إذا كنت قد حدّدت my_fragment_layout.xml
، يمكنك استخدام
رمز مثل هذا مع استبدال سمة XML android:name
باسم فئة
Fragment
:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container_view" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.example.compose.snippets.interop.MyFragment" />
وسِّع هذا المقتطف في ميزة "الإنشاء" على النحو التالي:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
إذا كنت بحاجة إلى استخدام عدة أقسام في التنسيق نفسه، تأكَّد من
تحديد معرّف فريد لكل FragmentContainerView
.
استدعاء إطار عمل Android من Compose
تعمل أداة Compose ضمن فئات إطار عمل Android. على سبيل المثال، يتم استضافتها
في فئات Android View، مثل Activity
أو Fragment
، وقد تستخدم فئات إطار عمل Android، مثل Context
أو موارد النظام
Service
أو BroadcastReceiver
.
لمزيد من المعلومات عن موارد النظام، يُرجى الاطّلاع على الموارد في ميزة "الإنشاء".
ترجمة المقطوعة الموسيقية
تتيح فئات CompositionLocal
تمرير البيانات بشكل ضمني من خلال الدوال القابلة للتجميع. ويتم عادةً تزويدها
بقيمة في عقدة معيّنة من شجرة واجهة المستخدم. ويمكن أن تستخدم هذه القيمة
العناصر المشتقة القابلة للتجميع بدون تحديد CompositionLocal
كمَعلمة في الدالة القابلة للتجميع.
يتم استخدام CompositionLocal
لنشر قيم أنواع إطار عمل Android في
Compose، مثل Context
أو Configuration
أو View
الذي يتم فيه استضافة
رمز Compose مع
LocalContext
أو
LocalConfiguration
أو
LocalView
المقابل.
يُرجى العِلم أنّ فئات CompositionLocal
تبدأ بالبادئة Local
لتحسين
إمكانية العثور عليها باستخدام ميزة الإكمال التلقائي في IDE.
يمكنك الوصول إلى القيمة الحالية لسمة CompositionLocal
باستخدام السمة current
. على سبيل المثال، يعرض الرمز البرمجي أدناه رسالة تذكير من خلال تقديم LocalContext.current
في الإجراء Toast.makeToast
.
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
للحصول على مثال أكثر اكتمالاً، اطّلِع على قسم دراسة الحالة: BroadcastReceivers في نهاية هذا المستند.
التفاعلات الأخرى
إذا لم تكن هناك خدمة محدّدة للتفاعل الذي تحتاجه، فإنّ أفضل الممارسات هي اتّباع الإرشادات العامة لإنشاء الرسائل، وهي تدفق البيانات للأسفل وتدفق الأحداث للأعلى (تمّت مناقشة ذلك بالتفصيل في مقالة التفكير في Compose). على سبيل المثال، يؤدي هذا الإجراء القابل للتجميع إلى تشغيل نشاط مختلف:
class OtherInteractionsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // get data from savedInstanceState setContent { MaterialTheme { ExampleComposable(data, onButtonClick = { startActivity(Intent(this, MyActivity::class.java)) }) } } } } @Composable fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) { Button(onClick = onButtonClick) { Text(data.title) } }
دراسة حالة: أجهزة استقبال البث
للحصول على مثال أكثر واقعية للميزات التي قد تحتاج إلى نقلها أو تنفيذها
في أداة "الإنشاء"، ولعرض CompositionLocal
وتأثيرات
جانبية، لنفترض أنّه يجب تسجيل
BroadcastReceiver
من
دالة قابلة للتركيب.
يستخدم الحلّ LocalContext
لاستخدام السياق الحالي، وتأثيرات rememberUpdatedState
وDisposableEffect
الجانبية.
@Composable fun SystemBroadcastReceiver( systemAction: String, onSystemEvent: (intent: Intent?) -> Unit ) { // Grab the current context in this part of the UI tree val context = LocalContext.current // Safely use the latest onSystemEvent lambda passed to the function val currentOnSystemEvent by rememberUpdatedState(onSystemEvent) // If either context or systemAction changes, unregister and register again DisposableEffect(context, systemAction) { val intentFilter = IntentFilter(systemAction) val broadcast = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { currentOnSystemEvent(intent) } } context.registerReceiver(broadcast, intentFilter) // When the effect leaves the Composition, remove the callback onDispose { context.unregisterReceiver(broadcast) } } } @Composable fun HomeScreen() { SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus -> val isCharging = /* Get from batteryStatus ... */ true /* Do something if the device is charging */ } /* Rest of the HomeScreen */ }
الخطوات التالية
بعد أن تعرّفت على واجهات برمجة التطبيقات للتشغيل التفاعلي عند استخدام ميزة "الإنشاء في "العروض" والعكس، يمكنك الاطّلاع على صفحة ملاحظات أخرى لمعرفة المزيد من المعلومات.
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون لغة JavaScript غير مفعّلة.
- اعتبارات أخرى
- الآثار الجانبية في ميزة "الإنشاء"
- البيانات على النطاق المحلي باستخدام CompositionLocal