FlowRow
e FlowColumn
são combináveis semelhantes a Row
e Column
, mas que diferem nos itens
fluem para a próxima linha quando o contêiner fica sem espaço. Isso cria
várias linhas ou colunas. O número de itens em uma linha também pode ser controlado
definindo maxItemsInEachRow
ou maxItemsInEachColumn
. Muitas vezes, é possível usar
FlowRow
e FlowColumn
para criar layouts responsivos — o conteúdo não será cortado
desativado se os itens forem muito grandes para uma dimensão e usando uma combinação de
maxItemsInEach*
com Modifier.weight(weight)
pode ajudar a criar layouts que
preencher/expandir a largura de uma linha ou coluna quando necessário.
O exemplo típico é para uma interface de chip ou filtragem:
Uso básico
Para usar FlowRow
ou FlowColumn
, crie esses elementos combináveis e posicione os itens
dentro dele que deve seguir o fluxo padrão:
@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") } }
Esse snippet resulta na interface mostrada acima, com itens fluindo automaticamente para a próxima linha quando não houver mais espaço na primeira linha.
Recursos do layout de fluxo
Os layouts de fluxo têm os seguintes recursos e propriedades que podem ser usados para criar layouts diferentes no seu app.
Organização do eixo principal: organização horizontal ou vertical
O eixo principal é aquele no qual os itens são dispostos (por exemplo, em
FlowRow
, os itens são organizados horizontalmente). O horizontalArrangement
em FlowRow
controla a forma como o espaço livre é distribuído entre os itens.
A tabela a seguir mostra exemplos de como definir horizontalArrangement
nos itens
para FlowRow
:
Organização horizontal definida em |
Resultado |
|
|
Para FlowColumn
, opções semelhantes estão disponíveis no verticalArrangement
, com
o padrão de Arrangement.Top
.
Disposição entre eixos
O eixo transversal é o eixo na direção oposta do eixo principal. Para
Em FlowRow
, este é o eixo vertical. Para alterar a forma como o
o conteúdo dentro do contêiner for organizado no eixo cruzado, use
verticalArrangement
para FlowRow
e horizontalArrangement
para
FlowColumn
.
Para FlowRow
, a tabela a seguir mostra exemplos de configuração de valores
verticalArrangement
nos itens:
Organização vertical definida em |
Resultado |
|
|
Para FlowColumn
, opções semelhantes estão disponíveis com horizontalArrangement
.
A organização padrão de eixo cruzado é Arrangement.Start
.
Alinhamento de itens individuais
Você pode querer posicionar itens individuais na linha com diferentes
alinhamentos. Ele é diferente de verticalArrangement
e
horizontalArrangement
, porque ela alinha os itens à linha atual. Você pode
aplicar isto com Modifier.align()
.
Por exemplo, quando os itens em uma FlowRow
têm alturas diferentes, a linha usa o
altura do maior item e aplica Modifier.align(alignmentOption)
ao
itens:
Alinhamento vertical definido em |
Resultado |
|
|
Para FlowColumn
, opções semelhantes estão disponíveis. O alinhamento padrão é
Alignment.Start
:
Máximo de itens na linha ou coluna
Os parâmetros maxItemsInEachRow
ou maxItemsInEachColumn
definem o
itens no eixo principal para permitir em uma linha antes de ir para a próxima. O
O padrão é Int.MAX_INT
, que permite o maior número possível de itens, desde que
o tamanho delas permite que se encaixem na linha.
Por exemplo, definir uma maxItemsInEachRow
força o layout inicial a apenas
tem 3 itens:
Nenhum máximo definido |
|
Itens de fluxo com carregamento lento
O ContextualFlowRow
e o ContextualFlowColumn
são recursos especializados
Versão de FlowRow
e FlowColumn
que permitem o carregamento lento do conteúdo.
da linha ou coluna do fluxo. Eles também fornecem informações sobre a posição dos itens
(índice, número da linha e tamanho disponível), por exemplo, se o item está no primeiro
linha de comando. Isso é útil para grandes conjuntos de dados e se você precisar de informações contextuais
sobre um item.
O parâmetro maxLines
limita o número de linhas exibidas, e o overflow
especifica o que será exibido quando for
alcançado, permitindo que você especifique um objeto expandIndicator
personalizado ou
collapseIndicator
.
Por exemplo, para mostrar um "+ (número de itens restantes)" ou "Mostrar menos" botão:
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") }
Pesos do item
O peso aumenta um item com base no fator dele e no espaço disponível na linha dele
foi colocado. É importante ressaltar que há uma diferença entre FlowRow
e Row
.
com a forma como os pesos são usados para calcular a largura de um item. Para Rows
, peso
é baseado em todos os itens da Row
. No FlowRow
, o peso é baseado no
itens na linha em que um item está colocado, nem todos os itens na
contêiner FlowRow
.
Por exemplo, se você tem quatro itens que se enquadram em uma linha, cada um com diferentes
de 1f, 2f, 1f
e 3f
, o peso total é 7f
. O espaço restante
em uma linha ou coluna serão divididas por 7f
. Então, a largura de cada item será
calculado usando: weight * (remainingSpace / totalWeight)
.
Você pode usar uma combinação de Modifier.weight
e itens máximos com FlowRow
ou
FlowColumn
para criar um layout semelhante a uma grade. Essa abordagem é útil para criar
layouts responsivos que se ajustam ao tamanho do seu dispositivo.
Há alguns exemplos diferentes do que é possível conseguir usando pesos. Um exemplo é uma grade em que os itens têm o mesmo tamanho, como mostrado abaixo:
Para criar uma grade de tamanhos iguais de itens, faça o seguinte:
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) } }
É importante ressaltar que, se você adicionar outro item e repeti-lo dez vezes em vez de nove, o
o último item ocupa a última coluna inteira, como o peso total da linha inteira
é 1f
:
É possível combinar pesos com outros Modifiers
, como
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
ou
Modifier.fillMaxWidth(fraction)
Todos esses modificadores funcionam em conjunto
permitem o dimensionamento responsivo de itens em uma FlowRow
(ou FlowColumn
).
Também é possível criar uma grade alternada de tamanhos diferentes, em que dois itens ocupa metade da largura cada, e um item ocupa a largura total do próximo coluna:
Você pode fazer isso com o seguinte código:
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)) } } }
Tamanho fracionário
Usando Modifier.fillMaxWidth(fraction)
, é possível especificar o tamanho do
contêiner que um item deve ocupar. Isso é diferente de como
Modifier.fillMaxWidth(fraction)
funciona quando aplicado a Row
ou Column
, em
que os itens Row/Column
ocupam uma porcentagem da largura restante, em vez de
toda a largura do contêiner.
Por exemplo, o código a seguir produz resultados diferentes ao usar FlowRow
.
x 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()
e fillMaxRowHeight()
Aplicar Modifier.fillMaxColumnWidth()
ou
Modifier.fillMaxRowHeight()
a um item dentro de FlowColumn
ou FlowRow
garante que os itens na mesma coluna ou linha ocupem a mesma largura ou altura que
para o maior item na coluna/linha.
Por exemplo, este exemplo usa FlowColumn
para exibir a lista de Android
sobremesas É possível ver a diferença na largura de cada item quando
Modifier.fillMaxColumnWidth()
é aplicado aos itens versus quando não são e
os itens são embalados.
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) ) } } }
|
|
Nenhuma alteração de largura definida (agrupamento de itens) |
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Conceitos básicos de layout do Compose
- ConstraintLayout no Compose
- Ações do editor {:#editor-actions}