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 { 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
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 Lambat (LazyColumn
, LazyRow
,
Pager
, dll.), pertimbangkan untuk menggunakan overload AndroidView
yang diperkenalkan dalam versi 1.4.0-rc01. Overload ini memungkinkan Compose menggunakan kembali
instance View
pokok saat komposisi yang memuatnya digunakan kembali seperti
hal untuk daftar Lambat.
Overload AndroidView
ini menambahkan 2 parameter tambahan:
onReset
- Callback yang dipanggil untuk memberi sinyal bahwaView
akan digunakan kembali. Nilai ini harus non-null untuk mengaktifkan penggunaan kembali View.onRelease
(opsional) - Callback yang dipanggil untuk menandakan bahwaView
telah keluar dari komposisi dan tidak akan digunakan kembali.
@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() } ) } } }
Fragment di Compose
Gunakan composable AndroidViewBinding
untuk menambahkan Fragment
di Compose.
AndroidViewBinding
memiliki penanganan khusus fragmen seperti menghapus
fragmen saat composable keluar dari komposisi.
Lakukan dengan meng-inflate XML yang berisi FragmentContainerView
sebagai holder untuk Fragment
.
Misalnya, jika memiliki my_fragment_layout.xml
yang ditentukan, Anda dapat menggunakan
kode seperti ini saat mengganti atribut XML android:name
dengan
nama class 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" />
Inflate fragmen ini di Compose sebagai berikut:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
Jika Anda perlu menggunakan beberapa fragmen dalam tata letak yang sama, pastikan Anda telah
menentukan ID unik untuk setiap FragmentContainerView
.
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.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Pertimbangan lainnya
- Efek samping di Compose
- Data yang dibatasi secara lokal dengan CompositionLocal