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 composables
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
Rowdoit se mesurer. - Le nœud racine
Rowdemande à son premier enfant,Image, de se mesurer. Imageest 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
Rowdemande à son deuxième enfant,Column, de se mesurer. - Le nœud
Columndemande à son premier enfantTextde se mesurer. - Le premier nœud
Textest un nœud feuille. Il renvoie donc une taille et renvoie des instructions de positionnement. - Le nœud
Columndemande à son deuxième enfantTextde se mesurer. - Le deuxième nœud
Textest un nœud feuille. Il renvoie donc une taille et renvoie des instructions de positionnement. - Maintenant que le nœud
Columna mesuré, dimensionné et positionné ses enfants, il peut déterminer sa propre taille et son propre emplacement. - Maintenant que le nœud racine
Rowa 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.
clickablefait réagir un composable suite à une entrée utilisateur et affiche une onde.paddingajoute de l'espace autour d'un élément.fillMaxWidthfait 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