FlowRow
et FlowColumn
sont des composables semblables à Row
et Column
, mais ils diffèrent dans le fait que les éléments sont transmis à la ligne suivante lorsque le conteneur est à court d'espace. Cela crée plusieurs
lignes ou colonnes. Le nombre d'éléments dans une ligne peut également être contrôlé en définissant maxItemsInEachRow
ou maxItemsInEachColumn
. Vous pouvez souvent utiliser FlowRow
et FlowColumn
pour créer des mises en page responsives. Le contenu ne sera pas tronqué si les éléments sont trop volumineux pour une dimension donnée. L'utilisation d'une combinaison de maxItemsInEach*
avec Modifier.weight(weight)
peut vous aider à créer des mises en page qui remplissent/augmentent la largeur d'une ligne ou d'une colonne si nécessaire.
Voici un exemple typique pour un chip ou une UI de filtrage:
Utilisation de base
Pour utiliser FlowRow
ou FlowColumn
, créez ces composables et placez-y les éléments qui doivent suivre le flux standard:
@Composable private fun FlowRowSimpleUsageExample() { FlowRow(modifier = Modifier.padding(8.dp)) { ChipItem("Price: High to Low") ChipItem("Avg rating: 4+") ChipItem("Free breakfast") ChipItem("Free cancellation") ChipItem("£50 pn") } }
Cet extrait permet d'obtenir l'interface utilisateur ci-dessus, les éléments étant automatiquement acheminés vers la ligne suivante lorsqu'il n'y a plus d'espace dans la première ligne.
Caractéristiques de la mise en page de flux
Les mises en page de flux disposent des fonctionnalités et propriétés suivantes que vous pouvez utiliser pour créer différentes mises en page dans votre application.
Disposition de l'axe principal: disposition horizontale ou verticale
L'axe principal est celui sur lequel les éléments sont disposés (par exemple, dans FlowRow
, les éléments sont disposés horizontalement). Le paramètre horizontalArrangement
dans FlowRow
contrôle la répartition de l'espace libre entre les éléments.
Le tableau suivant présente des exemples de définition de horizontalArrangement
sur des éléments pour FlowRow
:
Disposition horizontale définie sur |
Résultat |
|
|
Pour FlowColumn
, des options similaires sont disponibles avec verticalArrangement
, avec la valeur par défaut Arrangement.Top
.
Disposition des axes transversaux
L'axe transversal est l'axe opposé à l'axe principal. Par exemple, dans FlowRow
, il s'agit de l'axe vertical. Pour modifier la disposition du contenu global à l'intérieur du conteneur sur l'axe transversal, utilisez verticalArrangement
pour FlowRow
et horizontalArrangement
pour FlowColumn
.
Pour FlowRow
, le tableau suivant présente des exemples de définition de verticalArrangement
différents pour les éléments:
Disposition verticale définie sur |
Résultat |
|
|
Pour FlowColumn
, des options similaires sont disponibles avec horizontalArrangement
.
La disposition par défaut de l'axe transversal est Arrangement.Start
.
Alignement de l'élément individuel
Vous pouvez positionner des éléments individuels sur la ligne avec des alignements différents. Cette méthode est différente de verticalArrangement
et horizontalArrangement
, car elle aligne les éléments par rapport à la ligne actuelle. Vous pouvez l'appliquer avec Modifier.align()
.
Par exemple, lorsque les éléments d'une FlowRow
ont des hauteurs différentes, la ligne prend la hauteur de l'élément le plus grand et applique Modifier.align(alignmentOption)
à ces éléments:
Alignement vertical défini sur |
Résultat |
|
|
Des options similaires sont disponibles pour FlowColumn
. L'alignement par défaut est Alignment.Start
.
Nombre maximal d'éléments dans la ligne ou la colonne
Les paramètres maxItemsInEachRow
ou maxItemsInEachColumn
définissent le nombre maximal d'éléments sur l'axe principal à autoriser sur une ligne avant de passer à la ligne suivante. La valeur par défaut est Int.MAX_INT
, ce qui autorise autant d'éléments que possible, tant que leur taille leur permet de tenir dans la ligne.
Par exemple, la définition d'un maxItemsInEachRow
force la mise en page initiale à ne contenir que trois éléments:
Aucune valeur maximale définie |
|
Éléments du flux de chargement différé
ContextualFlowRow
et ContextualFlowColumn
sont une version spécialisée de FlowRow
et FlowColumn
qui vous permet de charger en différé le contenu de la ligne ou de la colonne de flux. Elles fournissent également des informations sur la position des éléments (index, numéro de ligne et taille disponible), par exemple si l'élément se trouve sur la première ligne. Cela est utile pour les grands ensembles de données et si vous avez besoin d'informations contextuelles sur un élément.
Le paramètre maxLines
limite le nombre de lignes affichées, et le paramètre overflow
spécifie ce qui doit s'afficher lorsqu'un dépassement d'éléments est atteint, ce qui vous permet de spécifier un expandIndicator
ou un collapseIndicator
personnalisé.
Par exemple, pour afficher un bouton "+ (nombre d'éléments restants)" ou "Afficher moins" :
val totalCount = 40 var maxLines by remember { mutableStateOf(2) } val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope -> val remainingItems = totalCount - scope.shownItemCount ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = { if (remainingItems == 0) { maxLines = 2 } else { maxLines += 5 } }) } ContextualFlowRow( modifier = Modifier .safeDrawingPadding() .fillMaxWidth(1f) .padding(16.dp) .wrapContentHeight(align = Alignment.Top) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), maxLines = maxLines, overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator( minRowsToShowCollapse = 4, expandIndicator = moreOrCollapseIndicator, collapseIndicator = moreOrCollapseIndicator ), itemCount = totalCount ) { index -> ChipItem("Item $index") }
Poids des articles
Le poids augmente un élément en fonction de son facteur et de l'espace disponible sur la ligne dans laquelle il a été placé. Il est important de noter qu'il existe une différence entre FlowRow
et Row
dans la façon dont les pondérations sont utilisées pour calculer la largeur d'un article. Pour Rows
, le poids est basé sur tous les éléments du Row
. Avec FlowRow
, la pondération est basée sur les éléments de la ligne dans laquelle un article est placé, et non sur tous les articles du conteneur FlowRow
.
Par exemple, si vous avez quatre éléments qui se trouvent tous sur une ligne, chacun avec une pondération différente de 1f, 2f, 1f
et 3f
, la pondération totale est de 7f
. L'espace restant dans une ligne ou une colonne sera divisé par 7f
. Ensuite, la largeur de chaque élément est calculée à l'aide de weight * (remainingSpace / totalWeight)
.
Vous pouvez utiliser une combinaison de Modifier.weight
et d'un nombre maximal d'éléments avec FlowRow
ou FlowColumn
pour créer une mise en page sous forme de grille. Cette approche est utile pour créer des mises en page responsives qui s'adaptent à la taille de votre appareil.
Il existe plusieurs exemples de ce que vous pouvez obtenir avec les pondérations. Par exemple, une grille dans laquelle les éléments sont de taille égale, comme illustré ci-dessous:
Pour créer une grille de tailles d'articles égales, vous pouvez procéder comme suit:
val rows = 3 val columns = 3 FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = rows ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .weight(1f) .clip(RoundedCornerShape(8.dp)) .background(MaterialColors.Blue200) repeat(rows * columns) { Spacer(modifier = itemModifier) } }
Il est important de noter que si vous ajoutez un autre élément et que vous le répétez 10 fois au lieu de 9, le dernier élément occupe l'intégralité de la dernière colonne, car la pondération totale pour l'ensemble de la ligne est 1f
:
Vous pouvez combiner les pondérations avec d'autres Modifiers
, tels que Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
ou Modifier.fillMaxWidth(fraction)
. Ces modificateurs fonctionnent tous conjointement pour permettre un dimensionnement responsif des éléments dans une FlowRow
(ou FlowColumn
).
Vous pouvez également créer une grille alternée de différentes tailles d'éléments, où deux éléments occupent chacun la moitié de la largeur et un élément sur toute la largeur de la colonne suivante:
Pour ce faire, utilisez le code suivant:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 2 ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .clip(RoundedCornerShape(8.dp)) .background(Color.Blue) repeat(6) { item -> // if the item is the third item, don't use weight modifier, but rather fillMaxWidth if ((item + 1) % 3 == 0) { Spacer(modifier = itemModifier.fillMaxWidth()) } else { Spacer(modifier = itemModifier.weight(0.5f)) } } }
Dimensionnement fractionnaire
Avec Modifier.fillMaxWidth(fraction)
, vous pouvez spécifier la taille du conteneur qu'un élément doit occuper. Cela diffère du fonctionnement de Modifier.fillMaxWidth(fraction)
lorsqu'il est appliqué à Row
ou à Column
, dans la mesure où les éléments Row/Column
occupent un pourcentage de la largeur restante, plutôt que de la largeur totale du conteneur.
Par exemple, le code suivant produit des résultats différents lorsque vous utilisez FlowRow
et Row
:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 3 ) { val itemModifier = Modifier .clip(RoundedCornerShape(8.dp)) Box(modifier = itemModifier.height(200.dp).width(60.dp).background(Color.Red)) Box(modifier = itemModifier.height(200.dp).fillMaxWidth(0.7f).background(Color.Blue)) Box(modifier = itemModifier.height(200.dp).weight(1f).background(Color.Magenta)) }
|
|
|
fillMaxColumnWidth()
et fillMaxRowHeight()
En appliquant Modifier.fillMaxColumnWidth()
ou Modifier.fillMaxRowHeight()
à un élément à l'intérieur d'un FlowColumn
ou d'un FlowRow
, vous vous assurez que les éléments d'une même colonne ou ligne occupent la même largeur ou la même hauteur que le plus grand élément de la colonne/ligne.
Par exemple, cet exemple utilise FlowColumn
pour afficher la liste des desserts Android. Vous pouvez voir la différence entre les largeurs de chaque élément lorsque Modifier.fillMaxColumnWidth()
est appliqué aux éléments, et lorsque ce n'est pas le cas et lorsque les éléments sont encapsulés.
FlowColumn( Modifier .padding(20.dp) .fillMaxHeight() .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), maxItemsInEachColumn = 5, ) { repeat(listDesserts.size) { Box( Modifier .fillMaxColumnWidth() .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Text( text = listDesserts[it], fontSize = 18.sp, modifier = Modifier.padding(3.dp) ) } } }
|
|
Aucune modification de largeur définie (encapsulation d'éléments) |
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Principes de base de la mise en page dans Compose
- ConstraintLayout dans Compose
- Actions de l'éditeur {:#editor-actions}