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
.
Arranjo de eixos cruzados
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
, o peso
é baseado em todos os itens no Row
. Com FlowRow
, o peso é baseado nos
itens na linha em que um item é colocado, e não em todos os itens no
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
).
Você também pode criar uma grade alternada de tamanhos de itens diferentes, em que dois itens ocupam metade da largura cada e um item ocupa a largura total da próxima coluna:
Para fazer isso, use 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
a largura de todo o contêiner.
Por exemplo, o código abaixo 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 notar a diferença na largura de cada item quando
Modifier.fillMaxColumnWidth()
é aplicado a eles em comparação com quando ele não é e
os itens são agrupados.
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}