In una UI di Compose puoi includere una gerarchia di Visualizzazione Android. Questo approccio è particolarmente utile se vuoi utilizzare elementi UI non ancora disponibili in Compose, ad esempio AdView
.
Questo approccio ti consente anche di riutilizzare le visualizzazioni personalizzate che hai progettato.
Per includere un elemento di visualizzazione o una gerarchia, utilizza l'elemento componibile AndroidView
. AndroidView
riceve una funzione lambda che restituisce
View
. AndroidView
fornisce anche un update
callback che viene richiamato quando la visualizzazione è gonfia. AndroidView
si ricompone
ogni volta che una lettura State
all'interno del callback cambia. AndroidView
, come molti
altri componibili integrati, richiede un parametro Modifier
che può essere usato, ad esempio, per impostare la propria posizione nell'elemento componibile principale.
@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
con associazione vista
Per incorporare un layout XML, utilizza l'API AndroidViewBinding
, fornita dalla libreria androidx.compose.ui:ui-viewbinding
. Per farlo, il tuo progetto deve attivare l'associazione di visualizzazioni.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView
in elenchi Lazy
Se utilizzi un AndroidView
in un elenco Lazy (LazyColumn
, LazyRow
, Pager
ecc.), valuta l'utilizzo dell'overload AndroidView
introdotto nella versione 1.4.0-rc01. Questo sovraccarico consente a Compose di riutilizzare
l'istanza View
sottostante quando la composizione contenitore viene riutilizzata,
come avviene per gli elenchi Lazy.
Questo sovraccarico di AndroidView
aggiunge altri 2 parametri:
onReset
: viene richiamato un callback per segnalare cheView
sta per essere riutilizzato. Deve essere un valore diverso da null per abilitare il riutilizzo delle visualizzazioni.onRelease
(facoltativo) - Un callback richiamato per segnalare cheView
è uscito dalla composizione e non verrà riutilizzato.
@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() } ) } } }
Frammenti in Compose
Utilizza il componibile AndroidViewBinding
per aggiungere un elemento Fragment
in Compose.
AndroidViewBinding
prevede una gestione specifica per i frammenti, ad esempio la rimozione del frammento quando il componibile lascia la composizione.
Per farlo, gonfia un XML contenente FragmentContainerView
come titolare del tuo Fragment
.
Ad esempio, se hai definito my_fragment_layout.xml
, potresti utilizzare
un codice come questo durante la sostituzione dell'attributo XML android:name
con il nome della classe di
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" />
Aumenta questo frammento in Compose come segue:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
Se devi utilizzare più frammenti nello stesso layout, assicurati di aver definito un ID univoco per ogni FragmentContainerView
.
Chiamare il framework Android da Compose
Compose opera all'interno delle classi del framework Android. Ad esempio, è ospitata su classi di Android View, come Activity
o Fragment
, e potrebbe utilizzare classi framework Android come Context
, risorse di sistema Service
o BroadcastReceiver
.
Per saperne di più sulle risorse di sistema, vedi Risorse in Compose.
Composizioni locali
Le classi CompositionLocal
consentono di trasmettere dati in modo implicito tramite funzioni componibili. Generalmente viene fornito un valore in un determinato nodo della struttura ad albero dell'interfaccia utente. Questo valore può
essere utilizzato dai suoi discendenti componibili senza dichiarare CompositionLocal
come parametro nella funzione componibile.
CompositionLocal
viene utilizzato per propagare i valori per i tipi di framework Android in Compose, ad esempio Context
, Configuration
o View
, in cui il codice di Compose è ospitato con i corrispondenti valori LocalContext
, LocalConfiguration
o LocalView
.
Tieni presente che le classi CompositionLocal
sono precedute dal prefisso Local
per una migliore rilevabilità con il completamento automatico nell'IDE.
Accedi al valore corrente di CompositionLocal
utilizzando la relativa proprietà current
. Ad esempio, il codice seguente mostra un messaggio toast fornendo LocalContext.current
nel metodo Toast.makeToast
.
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
Per un esempio più completo, consulta la sezione Case study: BroadcastRicevirs alla fine di questo documento.
Altre interazioni
Se non è stata definita un'utilità per l'interazione di cui hai bisogno, la best practice è seguire le linee guida generali di Compose: i dati scorrono verso il basso e gli eventi scorrono (trattati più approfonditamente in Thinking in Compose). Ad esempio, questo componibile avvia un'attività diversa:
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) } }
Case study: ricevitori di trasmissioni
Per un esempio più realistico delle funzionalità di cui vuoi eseguire la migrazione o l'implementazione in Compose, e per mostrare CompositionLocal
e gli effetti collaterali, supponiamo che sia necessario registrare BroadcastReceiver
da una funzione componibile.
La soluzione utilizza LocalContext
per usare il contesto corrente, nonché gli effetti collaterali di rememberUpdatedState
e 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 */ }
Passaggi successivi
Ora che conosci le API di interoperabilità quando utilizzi Compose in Views e viceversa, esplora la pagina Altre considerazioni per scoprire di più.
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Altre considerazioni
- Effetti collaterali in Compose
- Dati con ambito locale con ComposeLocal