می توانید یک سلسله مراتب Android View را در یک رابط کاربری Compose اضافه کنید. اگر میخواهید از عناصر رابط کاربری استفاده کنید که هنوز در Compose در دسترس نیستند، مانند AdView ، این رویکرد بسیار مفید است. این رویکرد همچنین به شما امکان می دهد از نماهای سفارشی که ممکن است طراحی کرده اید مجددا استفاده کنید.
برای گنجاندن یک عنصر view یا سلسله مراتب، از AndroidView composable استفاده کنید. AndroidView یک لامبدا ارسال می شود که یک View را برمی گرداند. AndroidView همچنین یک پاسخ بهروزرسانی update ارائه میدهد که وقتی نما باد شده است، فراخوانی میشود. AndroidView هر زمان که State خوانده شده در پاسخ به تماس تغییر کند، دوباره ترکیب می شود. AndroidView ، مانند بسیاری دیگر از اجزای سازنده داخلی، یک پارامتر Modifier را می گیرد که می تواند به عنوان مثال، برای تنظیم موقعیت آن در Composable والد استفاده شود.
@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 با view binding
برای جاسازی یک طرح بندی XML، از AndroidViewBinding API استفاده کنید که توسط کتابخانه androidx.compose.ui:ui-viewbinding ارائه شده است. برای انجام این کار، پروژه شما باید view binding را فعال کند.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView در لیست های تنبل
اگر از AndroidView در لیست Lazy استفاده می کنید ( LazyColumn ، LazyRow ، Pager ، و غیره)، از اضافه بار AndroidView که در نسخه 1.4.0-rc01 معرفی شده است استفاده کنید. این اضافه بار به Compose اجازه میدهد تا در صورت استفاده مجدد از ترکیب حاوی، مانند لیستهای Lazy، از نمونه View اصلی استفاده کند.
این اضافه بار AndroidView 2 پارامتر اضافی اضافه می کند:
-
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() } ) } } }
قطعات در نوشتن
از AndroidViewBinding composable برای افزودن یک Fragment در Compose استفاده کنید. AndroidViewBinding دارای مدیریت خاص قطعه است، مانند حذف قطعه زمانی که composable از ترکیب خارج می شود.
این کار را با باد کردن یک XML حاوی FragmentContainerView به عنوان نگهدارنده Fragment خود انجام دهید.
برای مثال، اگر my_fragment_layout.xml را تعریف کردهاید، میتوانید از کدی مانند این استفاده کنید، در حالی که ویژگی android:name XML را با نام کلاس 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" />
این قطعه را در Compose به صورت زیر باد کنید:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
اگر نیاز به استفاده از چند قطعه در یک طرح دارید، مطمئن شوید که یک شناسه منحصر به فرد برای هر FragmentContainerView تعریف کرده اید.
فراخوانی فریم ورک اندروید از Compose
Compose در کلاس های فریمورک اندروید عمل می کند. برای مثال، در کلاسهای Android View، مانند Activity یا Fragment ، میزبانی میشود و ممکن است از کلاسهای چارچوب Android مانند Context ، منابع سیستم، Service یا BroadcastReceiver استفاده کند.
برای کسب اطلاعات بیشتر در مورد منابع سیستم، به منابع در نوشتن مراجعه کنید.
ترکیب محلی ها
کلاسهای CompositionLocal اجازه میدهند تا دادهها را به طور ضمنی از طریق توابع ترکیبپذیر منتقل کنند. آنها معمولاً با یک مقدار در گره خاصی از درخت UI ارائه می شوند. این مقدار می تواند توسط نوادگان قابل ترکیب آن بدون اعلام CompositionLocal به عنوان یک پارامتر در تابع composable استفاده شود.
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") } }
برای مثال کاملتر، به بخش Case Study: BroadcastReceivers در انتهای این سند نگاهی بیندازید.
سایر تعاملات
اگر ابزاری برای تعاملی که نیاز دارید تعریف نشده است، بهترین کار این است که از دستورالعمل کلی نوشتن پیروی کنید، دادهها پایین میآیند، رویدادها جریان مییابند (که در Thinking in Compose به طور مفصلتر بحث شده است). به عنوان مثال، این composable یک فعالیت متفاوت را راه اندازی می کند:
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) } }
مطالعه موردی: گیرنده های پخش
برای مثال واقعیتر از ویژگیهایی که ممکن است بخواهید در Compose مهاجرت یا پیادهسازی کنید، و برای نمایش CompositionLocal و عوارض جانبی ، فرض کنید که یک BroadcastReceiver باید از یک تابع composable ثبت شود.
این راه حل از 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 */ }
مراحل بعدی
اکنون که APIهای قابلیت همکاری هنگام استفاده از Compose در Views و بالعکس را میشناسید، برای کسب اطلاعات بیشتر، صفحه سایر ملاحظات را بررسی کنید.
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- ملاحظات دیگر
- عوارض جانبی در Compose
- داده های محدوده محلی با CompositionLocal