يمكنك تضمين هيكلية طرق عرض Android في واجهة مستخدم Compose. ويكون هذا الأسلوب مفيدًا بشكل خاص إذا كنت تريد استخدام عناصر واجهة مستخدم غير متاحة بعد في Compose، مثل AdView.
يتيح لك هذا الأسلوب أيضًا إعادة استخدام طرق العرض المخصّصة التي صمّمتها.
لتضمين عنصر عرض أو بنية هرمية، استخدِم الدالة البرمجية القابلة للإنشاء AndroidView
. يتم تمرير دالة lambda إلى AndroidView تعرض View. توفّر AndroidView أيضًا update
دالة ردّ اتصال يتم استدعاؤها عند توسيع طريقة العرض. تتم إعادة إنشاء AndroidView
كلما تغيّرت قيمة State التي تم قراءتها في الدالة التنفيذية. تتضمّن الدالة AndroidView، مثل العديد من الدوال البرمجية القابلة للإنشاء المضمّنة الأخرى، المَعلمة Modifier التي يمكن استخدامها، مثلاً، لضبط موضعها في الدالة البرمجية القابلة للإنشاء الرئيسية.
@Composable fun CustomView() { var selectedItem by remember { mutableIntStateOf(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 في قائمة Lazy (LazyColumn أو LazyRow أو Pager أو غير ذلك)، ننصحك باستخدام AndroidView
الذي تم تقديمه في الإصدار 1.4.0-rc01. تتيح عملية التحميل الزائد هذه لـ Compose إعادة استخدام مثيل View الأساسي عند إعادة استخدام التركيب الحاوي كما هو، كما هو الحال مع القوائم الكسولة.
تضيف هذه الزيادة في التحميل الزائد AndroidView مَعلمتَين إضافيتَين:
-
onReset: دالة يتم استدعاؤها للإشارة إلى أنّViewسيتم إعادة استخدامه. يجب أن تكون هذه القيمة غير فارغة لتفعيل إعادة استخدام العرض. -
onRelease(اختياري): دالة ردّ يتم استدعاؤها للإشارة إلى أنّViewقد خرج من التركيب ولن تتم إعادة استخدامه مرة أخرى.
@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() } ) } } }
الأجزاء في Compose
استخدِم العنصر القابل للإنشاء AndroidFragment لإضافة Fragment في Compose.
تتضمّن AndroidFragment معالجة خاصة بالجزء، مثل إزالة الجزء عندما يغادر العنصر القابل للإنشاء التركيب.
لتضمين جزء، استخدِم العنصر القابل للإنشاء AndroidFragment. يمكنك تمرير فئة Fragment إلى AndroidFragment، التي تضيف بعد ذلك مثيلاً من هذه الفئة مباشرةً إلى التركيب. توفّر السمة AndroidFragment أيضًا عنصر fragmentState لإنشاء AndroidFragment بحالة معيّنة، وarguments لتمريرها إلى الجزء الجديد، وonUpdate ردّ اتصال يوفّر الجزء من التركيب. مثل العديد من العناصر القابلة للإنشاء المضمّنة الأخرى، تقبل AndroidFragment المَعلمة Modifier التي يمكنك استخدامها، على سبيل المثال، لضبط موضعها في العنصر القابل للإنشاء الرئيسي.
استخدِم الدالة AndroidFragment في Compose على النحو التالي:
@Composable fun FragmentInComposeExample() { AndroidFragment<MyFragment>() }
استدعاء إطار عمل Android من Compose
تعمل Compose ضمن فئات إطار عمل Android. على سبيل المثال، تتم استضافته على فئات Android View، مثل Activity أو Fragment، وقد يستخدم فئات إطار عمل Android، مثل Context أو موارد النظام Service أو BroadcastReceiver.
لمزيد من المعلومات حول موارد النظام، يمكنك الاطّلاع على الموارد في Compose.
Composition Locals
تسمح فئات CompositionLocal بتمرير البيانات ضمنيًا من خلال الدوال القابلة للإنشاء. ويتم عادةً توفيرها بقيمة في عقدة معيّنة من شجرة واجهة المستخدم. ويمكن أن تستخدم العناصر التابعة المركّبة هذه القيمة بدون تعريف CompositionLocal كمعلَمة في الدالة المركّبة.
يُستخدَم CompositionLocal لنقل قيم أنواع إطار عمل Android في Compose، مثل Context أو Configuration أو View الذي تتم فيه استضافة رمز Compose مع LocalContext أو LocalConfiguration أو LocalView المقابل.
يُرجى العِلم أنّ فئات CompositionLocal مسبوقة بـ Local لتسهيل العثور عليها باستخدام ميزة الإكمال التلقائي في بيئة التطوير المتكاملة.
يمكنك الوصول إلى القيمة الحالية لـ 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") } }
مستقبِلات البث
لعرض 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 */ }
تفاعلات أخرى
إذا لم تكن هناك أداة مساعدة محدّدة للتفاعل الذي تحتاجه، فإنّ أفضل ممارسة هي اتّباع إرشادات Compose العامة، أي تنتقل البيانات إلى الأسفل، وتنتقل الأحداث إلى الأعلى (تمت مناقشة ذلك بالتفصيل في التفكير في 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) } }