Menggunakan View di Compose

Anda bisa menyertakan hierarki Android View di UI Compose. Pendekatan ini sangat berguna jika Anda ingin menggunakan elemen UI yang belum tersedia di Compose, seperti AdView. Pendekatan ini juga memungkinkan Anda menggunakan kembali tampilan kustom yang mungkin sudah Anda desain.

Untuk menyertakan elemen tampilan atau hierarki, gunakan composable AndroidView . AndroidView dimasukkan lambda yang menampilkan View. AndroidView juga menyediakan callback update yang dipanggil saat tampilan di-inflate. AndroidView akan merekomposisi setiap kali pembacaan State dalam callback berubah. AndroidView, seperti banyak composable bawaan lainnya, memerlukan parameter Modifier yang dapat digunakan, misalnya, untuk menyetel posisinya di composable induk.

@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 dengan view binding

Untuk menyematkan tata letak XML, gunakan AndroidViewBinding API, yang disediakan oleh library androidx.compose.ui:ui-viewbinding. Untuk melakukannya, project Anda harus mengaktifkan binding tampilan.

@Composable fun AndroidViewBindingExample() {     AndroidViewBinding(ExampleLayoutBinding::inflate) {         exampleView.setBackgroundColor(Color.GRAY)     } }

AndroidView dalam Daftar lambat

Jika Anda menggunakan AndroidView dalam daftar Lazy (LazyColumn, LazyRow, Pager, dll.), pertimbangkan untuk menggunakan penggantian AndroidView yang diperkenalkan dalam versi 1.4.0-rc01. Overload ini memungkinkan Compose menggunakan kembali instance View yang mendasarinya saat komposisi yang memuatnya digunakan kembali seperti halnya untuk daftar Lazy.

Overload AndroidView ini menambahkan 2 parameter tambahan:

  • onReset - Callback yang dipanggil untuk memberi sinyal bahwa View akan digunakan kembali. Nilai ini tidak boleh null untuk mengaktifkan penggunaan ulang View.
  • onRelease (opsional) - Callback yang dipanggil untuk memberi sinyal bahwa View telah keluar dari komposisi dan tidak akan digunakan kembali.

@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()                 }             )         }     } }

Fragment di Compose

Gunakan composable AndroidFragment untuk menambahkan Fragment di Compose. AndroidFragment memiliki penanganan khusus fragmen seperti menghapus fragmen saat composable keluar dari komposisi.

Untuk menyertakan fragmen, gunakan composable AndroidFragment. Anda meneruskan class Fragment ke AndroidFragment, yang kemudian menambahkan instance class tersebut langsung ke komposisi. AndroidFragment juga menyediakan objek fragmentState untuk membuat AndroidFragment dengan status tertentu, arguments untuk diteruskan ke fragmen baru, dan callback onUpdate yang menyediakan fragmen dari komposisi. Seperti banyak composable bawaan lainnya, AndroidFragment menerima parameter Modifier yang dapat Anda gunakan, misalnya, untuk menyetel posisinya di composable induk.

Panggil AndroidFragment di Compose sebagai berikut:

@Composable fun FragmentInComposeExample() {     AndroidFragment<MyFragment>() } 

Memanggil framework Android dari Compose

Compose beroperasi dalam class framework Android. Misalnya, class tersebut dihosting di class View Android, seperti Activity atau Fragment, dan mungkin menggunakan class framework Android seperti Context, resource sistem, Service, atau BroadcastReceiver.

Untuk mempelajari resource sistem lebih lanjut, lihat Resource dalam Compose.

Lokal Komposisi

Dengan class CompositionLocal, penerusan data secara implisit bisa dilakukan melalui fungsi composable. Fungsi ini biasanya diberi nilai dalam node tertentu dari pohon UI. Nilai tersebut dapat digunakan oleh turunan composable-nya tanpa mendeklarasikan CompositionLocal sebagai parameter dalam fungsi composable.

CompositionLocal digunakan untuk mengisi nilai jenis framework Android di Compose seperti Context, Configuration, atau View di mana kode Compose dihosting dengan kode yang sesuai LocalContext, LocalConfiguration, atau LocalView. Perhatikan bahwa class CompositionLocal diawali dengan Local agar mendapatkan visibilitas yang lebih baik dengan pelengkapan otomatis di IDE.

Akses nilai CompositionLocal saat ini menggunakan properti current. Misalnya, kode di bawah ini menampilkan pesan toast dengan menyediakan LocalContext.current ke dalam metode Toast.makeToast.

@Composable fun ToastGreetingButton(greeting: String) {     val context = LocalContext.current     Button(onClick = {         Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show()     }) {         Text("Greet")     } }

Untuk contoh yang lebih lengkap, lihat bagian Studi Kasus: BroadcastReceivers di akhir dokumen ini.

Interaksi lainnya

Jika tidak ada utilitas yang ditetapkan untuk interaksi yang Anda butuhkan, praktik terbaiknya adalah mengikuti pedoman Compose umum, data mengalir ke bawah, peristiwa mengalir ke atas (dibahas lebih jauh lagi di bagian Paradigma Compose). Misalnya, composable ini akan meluncurkan aktivitas yang berbeda:

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)     } }

Studi Kasus: Penerima siaran

Untuk contoh fitur yang lebih realistis, Anda mungkin ingin bermigrasi atau menerapkannya di Compose dan menampilkan CompositionLocal dan efek samping, misalnya BroadcastReceiver harus didaftarkan dari fungsi composable.

Solusi ini memanfaatkan LocalContext untuk menggunakan konteks saat ini, serta efek samping rememberUpdatedState dan 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 */ }

Langkah berikutnya

Setelah Anda mengetahui API interoperabilitas saat menggunakan Compose di View dan sebaliknya, jelajahi halaman Pertimbangan lainnya untuk mempelajari lebih lanjut.