Jetpack Compose facilite grandement la conception et la création de l'interface utilisateur de votre application. Il transforme l'état en éléments d'interface utilisateur via trois étapes distinctes :
- La composition des éléments
- La mise en page des éléments
- Le dessin des éléments
Ce document se concentre sur la mise en page. Il explique certains des composants fondamentaux proposés par Compose pour mettre en page les éléments d'interface utilisateur.
Objectifs des mises en page dans Compose
L'implémentation Jetpack Compose du système de mise en page répond à deux objectifs principaux :
- Hautes performances
- Création facile de mises en page personnalisées
Principes de base des fonctions modulables
Les fonctions composables sont les éléments de base de Compose. Une fonction modulable est une Unit
émettant une fonction qui décrit une partie de votre interface utilisateur. Elle utilise des entrées et génère ce qui s'affiche à l'écran. Pour en savoir plus sur les composables, consultez la documentation sur le modèle mental de Compose.
Une fonction composable peut émettre plusieurs éléments d'interface utilisateur. Toutefois, si vous n'indiquez pas comment les organiser, Compose peut organiser les éléments d'une façon qui ne vous convient pas. Par exemple, ce code génère deux éléments de texte :
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
Sans indications sur la façon dont vous souhaitez les organiser, Compose empile les éléments de texte les uns sur les autres, les rendant illisibles :
Compose fournit une collection de mises en page prêtes à l'emploi pour vous aider à organiser les éléments d'interface utilisateur et à définir vos propres mises en page plus spécialisées.
Composants de mise en page standards
Dans de nombreux cas, vous pouvez simplement utiliser les éléments de mise en page standards de Compose.
Utilisez Column
pour placer les éléments verticalement sur l'écran.
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
De même, utilisez Row
pour positionner les éléments horizontalement sur l'écran. Column
et Row
permettent tous deux de configurer l'alignement des éléments qu'ils contiennent.
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
Utilisez Box
pour superposer des éléments. Box
permet également de configurer un alignement spécifique des éléments qu'il contient.
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
Souvent, ces composants de base suffisent. Vous pouvez écrire votre propre fonction modulable pour combiner ces mises en page dans une mise en page plus élaborée adaptée à votre application.
Pour définir la position des enfants dans un élément Row
, définissez les arguments horizontalArrangement
et verticalAlignment
. Pour un élément Column
, définissez les arguments verticalArrangement
et horizontalAlignment
:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
Le modèle de mise en page
Dans le modèle de mise en page, l'arborescence de l'UI est mise en page en une seule fois. Chaque nœud doit d'abord se mesurer, puis mesurer les éléments enfants de manière récursive, en leur transmettant les contraintes de taille. Ensuite, les nœuds feuilles sont redimensionnés et positionnés, tandis que les tailles et les instructions de positionnement résolues sont renvoyées à l'arborescence.
En bref, les parents se mesurent avant leurs enfants, mais ils sont dimensionnés et positionnés après leurs enfants.
Prenons l'exemple de la fonction SearchResult
suivante.
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
Cette fonction génère l'arborescence d'interface utilisateur ci-dessous.
SearchResult
Row
Image
Column
Text
Text
Dans l'exemple SearchResult
, l'arborescence de l'interface utilisateur suit cet ordre :
- Le nœud racine
Row
doit se mesurer. - Le nœud racine
Row
demande à son premier enfant,Image
, de se mesurer. Image
est un nœud feuille (nœud qui n'a pas d'enfants). Il renvoie donc une taille et renvoie des instructions de positionnement.- Le nœud racine
Row
demande à son deuxième enfant,Column
, de se mesurer. - Le nœud
Column
demande à son premier enfantText
de se mesurer. - Le premier nœud
Text
est un nœud feuille. Il renvoie donc une taille et renvoie des instructions de positionnement. - Le nœud
Column
demande à son deuxième enfantText
de se mesurer. - Le deuxième nœud
Text
est un nœud feuille. Il renvoie donc une taille et renvoie des instructions de positionnement. - Maintenant que le nœud
Column
a mesuré, dimensionné et positionné ses enfants, il peut déterminer sa propre taille et son propre emplacement. - Maintenant que le nœud racine
Row
a mesuré, dimensionné et positionné ses enfants, il peut déterminer sa propre taille et son propre emplacement.
Performances
Compose atteint de hautes performances en ne mesurant les enfants qu'une seule fois. Il peut ainsi gérer efficacement les arborescences profondes. Si un élément mesurait deux fois son enfant et que celui-ci mesurait deux fois chacun de ses enfants, et ainsi de suite, une seule tentative de mise en page de l'ensemble de l'UI entraînerait une charge de travail considérable. Il serait donc difficile de conserver le niveau de performances de l'application.
Si, pour une raison quelconque, votre mise en page nécessite plusieurs mesures, Compose propose un système spécial de mesures intrinsèques. Pour en savoir plus sur cette fonctionnalité, consultez la section Mesures intrinsèques dans les mises en page Compose.
Étant donné que les mesures et les positionnements constituent des sous-phases distinctes de la mise en page, toutes les modifications qui n'affectent que le positionnement des éléments, et non les mesures, peuvent être exécutées séparément.
Utiliser des modificateurs dans les mises en page
Comme indiqué dans la section Modificateurs Compose, vous pouvez utiliser des modificateurs pour décorer ou enrichir vos composables. Ils sont essentiels pour personnaliser votre mise en page. Par exemple, voici plusieurs modificateurs associés les uns aux autres pour personnaliser l'élément ArtistCard
:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
Dans le code ci-dessus, vous remarquerez que plusieurs fonctions sont utilisées.
clickable
fait réagir un composable suite à une entrée utilisateur et affiche une onde.padding
ajoute de l'espace autour d'un élément.fillMaxWidth
fait en sorte que le composable remplisse la largeur maximale qui lui est attribuée par son parent.size()
spécifie la largeur et la hauteur préférées d'un élément.
Mises en page à défilement
Pour en savoir plus sur les mises en page á défilement, consultez la documentation sur les gestes Compose.
Pour en savoir plus sur les listes standards et les listes différées, consultez la documentation spécifique aux listes Compose.
Mises en page responsives
Une mise en page doit être conçue en tenant compte des différentes orientations d'écran et des différents facteurs de forme possibles. Compose propose des mécanismes prêts à l'emploi permettant d'adapter les mises en page modulables à différentes configurations d'écran.
Contraintes
Pour déterminer les contraintes du parent et concevoir la mise en page en conséquence, vous pouvez utiliser un élément BoxWithConstraints
. Les contraintes de mesure se trouvent dans le champ d'application du lambda de contenu. Vous pouvez utiliser ces contraintes de mesure afin de créer différentes mises en page pour différentes configurations d'écran :
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
Mises en page basées sur les emplacements
Compose fournit une grande variété de composables basés sur Material Design avec la dépendance androidx.compose.material:material
(ajoutée lors de la création d'un projet Compose dans Android Studio) pour faciliter la création de l'interface utilisateur. Les éléments tels que Drawer
, FloatingActionButton
et TopAppBar
sont tous fournis.
Les composants Material font beaucoup appel aux API d'emplacement, un modèle proposé par Compose pour ajouter une couche de personnalisation aux composables. Cette approche rend les composants plus flexibles, car ils acceptent un élément enfant qui peut se configurer lui-même au lieu d'avoir à exposer tous ses paramètres de configuration.
Ces emplacements laissent dans l'UI un espace vide que le développeur peut remplir comme bon lui semble. Par exemple, voici les emplacements que vous pouvez personnaliser dans un objet TopAppBar
:
Les composables utilisent généralement un lambda content
(content: @Composable
() -> Unit
). Les API d'emplacement présentent plusieurs paramètres content
pour des utilisations spécifiques.
Par exemple, TopAppBar
vous permet de fournir le contenu pour title
, navigationIcon
et actions
.
Par exemple, Scaffold
vous permet d'implémenter une UI avec la structure de mise en page Material Design de base. Scaffold
fournit des emplacements pour les composants Material de niveau supérieur les plus courants, tels que TopAppBar
, BottomAppBar
, FloatingActionButton
et Drawer
. Avec Scaffold
, vous pouvez facilement vous assurer que ces composants sont correctement positionnés et interagissent comme prévu.
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Modificateurs Compose
- Kotlin pour Jetpack Compose
- Composants et mises en page Material