Dans Compose, les éléments d'interface utilisateur sont représentés par des fonctions modulables qui émettent une partie d'interface utilisateur lorsqu'elles sont appelées, laquelle est alors ajoutée à une arborescence d'interface utilisateur qui s'affiche à l'écran. Chaque élément de l'interface utilisateur a un parent et peut avoir de nombreux enfants. Chaque élément est également situé dans son parent, spécifié sous la forme d'une position (x, y) et d'une taille, indiquée en tant que width
et height
.
Les parents définissent les contraintes de leurs éléments enfants. Un élément est invité à définir sa taille dans ces contraintes. Ces contraintes limitent les width
et height
maximales d'un élément. Si un élément comporte des éléments enfants, il peut mesurer chaque enfant pour déterminer sa taille. Une fois qu'un élément détermine et indique sa propre taille, il peut définir comment positionner ses éléments enfants par rapport à lui-même, comme décrit en détail dans Créer des mises en page personnalisées.
La mise en page de chaque nœud dans l'arborescence de l'interface utilisateur s'effectue en trois étapes. Chaque nœud doit :
- Mesurer tout élément enfant
- Déterminer sa propre taille
- Placer ses éléments enfants
L'utilisation des champs d'application définit quand mesurer et placer vos enfants.
Vous ne pouvez mesurer une mise en page que lors des passes de mesure et de mise en page. De plus, un enfant ne peut être placé que pendant les passes de mise en page (et seulement après avoir été mesuré). En raison des champs d'application Compose tels que MeasureScope
et PlacementScope
, cette opération est appliquée au moment de la compilation.
Utiliser le modificateur de mise en page
Vous pouvez utiliser le modificateur layout
pour changer la façon dont un élément est mesuré et mis en page. Layout
est un lambda. Ses paramètres incluent l'élément que vous pouvez mesurer, transmis en tant que measurable
, ainsi que les contraintes entrantes de ce composable, transmises en tant que constraints
. Un modificateur de mise en page personnalisé peut se présenter comme ceci :
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
Affichons un Text
à l'écran et contrôlons la distance entre le haut et la ligne de la première ligne de texte. C'est exactement ce que fait le modificateur paddingFromBaseline
, que nous intégrons ici à titre d'exemple.
Pour ce faire, utilisez le modificateur layout
pour placer manuellement le composable sur l'écran. Voici le comportement souhaité lorsque la marge intérieure supérieure de Text
est définie sur 24.dp
:
Voici le code permettant de créer cet espacement :
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
Voici ce qui se passe dans ce code :
- Dans le paramètre lambda
measurable
, vous mesurez leText
représenté par le paramètre mesurable en appelantmeasurable.measure(constraints)
. - Vous précisez la taille du composable en appelant la méthode
layout(width, height)
, qui fournit également un lambda utilisé pour placer les éléments encapsulés. Dans ce cas, il s'agit de la hauteur entre la dernière référence et la marge intérieure supérieure ajoutée. - Vous pouvez positionner les éléments encapsulés sur l'écran en appelant
placeable.place(x, y)
. Si les éléments encapsulés ne sont pas placés, ils ne seront pas visibles. La positiony
correspond à la marge supérieure, c'est-à-dire à la première ligne du texte.
Pour vérifier que tout fonctionne comme prévu, utilisez ce modificateur sur un Text
:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
Créer des mises en page personnalisées
Le modificateur layout
ne modifie que le composable appelant. Pour mesurer et mettre en page plusieurs composables, utilisez plutôt le composable Layout
. Ce composable vous permet de mesurer et de positionner manuellement les enfants. Toutes les mises en page de niveau supérieur, comme Column
et Row
, sont créées avec le composable Layout
.
Créons une version très basique de Column
. La plupart des mises en page personnalisées suivent le modèle suivant :
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
Comme pour le modificateur layout
, measurables
est la liste des enfants à mesurer et constraints
les contraintes du parent.
En suivant la même logique qu'auparavant, MyBasicColumn
peut être intégré comme suit :
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
Les composables enfants sont limités par les contraintes Layout
(sans les contraintes minHeight
) et ils sont placés selon la yPosition
du composable précédent.
Voici comment ce composable personnalisé serait utilisé :
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
Orientation de la mise en page
Modifiez l'orientation de la mise en page d'un composable en modifiant la composition LocalLayoutDirection
en local.
Si vous positionnez des composables manuellement sur l'écran, LayoutDirection
fait partie du LayoutScope
du modificateur layout
ou du composable Layout
.
Lorsque vous utilisez layoutDirection
, placez des composables à l'aide de place
. Contrairement à la méthode placeRelative
, place
ne change pas en fonction de l'orientation de la mise en page (de gauche à droite ou de droite à gauche).
Mises en page personnalisées à l'œuvre
Pour en savoir plus sur les mises en page et les modificateurs, consultez la page Mises en page de base dans Compose. Pour découvrir comment utiliser les mises en page personnalisées, consultez les exemples de création de mises en page personnalisées dans Compose.
En savoir plus
Pour en savoir plus sur les mises en page personnalisées dans Compose, consultez les ressources supplémentaires suivantes.
Vidéos
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Mesures intrinsèques dans les mises en page Compose
- Éléments graphiques dans Compose
- Modificateurs Compose