Vous pouvez inclure une hiérarchie des vues Android dans une interface utilisateur Compose. Cette approche est particulièrement utile si vous souhaitez utiliser des éléments d'interface utilisateur qui ne sont pas encore disponibles dans Compose, comme AdView.
Cela vous permet également de réutiliser des vues personnalisées.
Pour inclure un élément ou une hiérarchie de vues, utilisez le AndroidView
composable. AndroidView reçoit un lambda qui renvoie un
View. AndroidView fournit également un rappel update, qui est appelé lorsque la vue est gonflée. AndroidView se recompose chaque fois qu'une lecture State du rappel change. Comme de nombreux autres composables intégrés, AndroidView utilise un paramètre Modifier qui peut servir, par exemple, à définir sa position dans le composable parent.
@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 avec liaison de vue
Pour intégrer une mise en page XML, utilisez l'
AndroidViewBinding
API fournie par la androidx.compose.ui:ui-viewbinding bibliothèque. Pour ce
faire, votre projet doit activer la liaison de vue.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView dans les listes différées
Si vous utilisez un AndroidView dans une liste différée (LazyColumn, LazyRow,
Pager, etc.), envisagez d'utiliser la AndroidView
surcharge introduite dans la version 1.4.0-rc01. Cette surcharge permet à Compose de réutiliser l'instance View sous-jacente lorsque la composition contenant est réutilisée, comme c'est le cas pour les listes différées.
Cette surcharge de AndroidView ajoute deux paramètres supplémentaires :
onReset: rappel appelé pour signaler que leViewest sur le point d'être réutilisé. Cette valeur doit être non nulle pour activer la réutilisation de la vue.onRelease(facultatif) : rappel appelé pour signaler que laViewa quitté la composition et ne sera plus réutilisée.
@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() } ) } } }
Fragments dans Compose
Utilisez le composable AndroidFragment pour ajouter un Fragment dans Compose.
AndroidFragment offre une gestion spécifique au fragment, comme la suppression du fragment lorsque le composable quitte la composition.
Pour inclure un fragment, utilisez le AndroidFragment
composable. Vous transmettez une classe Fragment à AndroidFragment, qui ajoute ensuite
une instance de cette classe directement dans la composition. AndroidFragment fournit également un objet fragmentState pour créer l'AndroidFragment avec un état donné, des arguments à transmettre au nouveau fragment et un rappel onUpdate qui fournit le fragment à partir de la composition. Comme de nombreux autres composables intégrés, AndroidFragment accepte un paramètre Modifier que vous pouvez utiliser, par exemple, pour définir sa position dans le composable parent.
Appelez AndroidFragment dans Compose comme suit :
@Composable fun FragmentInComposeExample() { AndroidFragment<MyFragment>() }
Appeler le framework Android à partir de Compose
Compose fonctionne dans les classes du framework Android. Par exemple, il est hébergé sur les classes de vues Android, comme Activity ou Fragment, et peut utiliser des classes du framework Android comme Context, les ressources système, Service ou encore BroadcastReceiver.
Pour en savoir plus sur les ressources système, consultez la section Ressources dans Compose.
Compositions locales
Les classes CompositionLocal permettent de transmettre des données implicitement via des fonctions modulables. Elles sont généralement accompagnées d'une valeur dans un nœud spécifique de l'arborescence de l'interface utilisateur. Cette valeur peut être utilisée par ses descendants composables sans déclarer le CompositionLocal en tant que paramètre dans la fonction modulable.
CompositionLocal permet de propager des valeurs pour les types de frameworks Android dans Compose, tels que Context, Configuration ou View, dans lesquels le code Compose est hébergé avec les éléments LocalContext, LocalConfiguration ou LocalView correspondants.
Notez que les classes CompositionLocal sont précédées de Local pour une meilleure visibilité avec la saisie semi-automatique dans l'IDE.
Pour accéder à la valeur actuelle de CompositionLocal, utilisez sa propriété current. Par exemple, le code ci-dessous affiche un toast en fournissant le LocalContext.current dans la méthode Toast.makeToast.
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
Broadcast receivers
Pour illustrer CompositionLocal et effets
secondaires, si un
BroadcastReceiver doit être enregistré à partir
d'une fonction modulable, utilisez LocalContext pour utiliser le contexte actuel, ainsi que
rememberUpdatedState et DisposableEffect effets secondaires.
@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 */ }
Autres interactions
Si aucun utilitaire n'est défini pour l'interaction dont vous avez besoin, nous vous recommandons de suivre les consignes générales de Compose : le flux de données descend, le flux d'événements monte. Plus de détails sont disponibles dans Raisonnement dans Compose. Par exemple, ce composable lance une autre activité :
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) } }