FlowRow
e FlowColumn
sono componibili simili a Row
e Column
, ma si differenziano per il fatto che gli elementi
scorrono nella riga successiva quando il contenitore esaurisce lo spazio. In questo modo vengono create
più righe o colonne. Il numero di elementi in una riga può essere controllato anche
impostando maxItemsInEachRow
o maxItemsInEachColumn
. Puoi spesso usare FlowRow
e FlowColumn
per creare layout adattabili: i contenuti non verranno tagliati se gli elementi sono troppo grandi per una dimensione e l'utilizzo di una combinazione di maxItemsInEach*
con Modifier.weight(weight)
può aiutarti a creare layout che riempiono/espandono la larghezza di una riga o di una colonna quando necessario.
L'esempio tipico è per un chip o un'interfaccia utente di filtro:
Utilizzo di base
Per utilizzare FlowRow
o FlowColumn
, crea questi componibili e posiziona al suo interno gli elementi che devono seguire la procedura 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") } }
Questo snippet restituisce l'interfaccia utente mostrata sopra, con gli elementi che passano automaticamente alla riga successiva quando non c'è più spazio nella prima riga.
Caratteristiche del layout del flusso
I layout di flusso hanno le seguenti funzionalità e proprietà che puoi utilizzare per creare layout diversi nella tua app.
Disposizione dell'asse principale: orizzontale o verticale
L'asse principale è l'asse su cui sono disposti gli elementi (ad esempio, in FlowRow
gli elementi sono disposti orizzontalmente). Il parametro horizontalArrangement
in FlowRow
controlla il modo in cui lo spazio libero viene distribuito tra gli elementi.
La tabella seguente mostra esempi di impostazione di horizontalArrangement
per gli elementi di FlowRow
:
Disposizione orizzontale impostata su |
Risultato |
|
|
Per FlowColumn
, sono disponibili opzioni simili con verticalArrangement
, con
il valore predefinito di Arrangement.Top
.
Disposizione dell'asse trasversale
L'asse trasversale corrisponde all'asse nella direzione opposta all'asse principale. Ad
esempio, in FlowRow
, questo è l'asse verticale. Per modificare il modo in cui i contenuti complessivi all'interno del container sono disposti sull'asse trasversale, utilizza verticalArrangement
per FlowRow
e horizontalArrangement
per FlowColumn
.
Per FlowRow
, la tabella seguente mostra esempi di impostazione di verticalArrangement
diverse per gli elementi:
Disposizione verticale impostata su |
Risultato |
|
|
Per FlowColumn
, sono disponibili opzioni simili con horizontalArrangement
.
La disposizione predefinita degli assi trasversali è Arrangement.Start
.
Allineamento di singoli elementi
Ti consigliamo di posizionare singoli elementi all'interno della riga con allineamenti diversi. È diverso da verticalArrangement
e
horizontalArrangement
in quanto allinea gli elementi all'interno della riga corrente. Puoi
applicarla con Modifier.align()
.
Ad esempio, quando gli elementi in FlowRow
hanno altezze diverse, la riga prende l'altezza
dell'elemento più grande e applica Modifier.align(alignmentOption)
agli
elementi:
Allineamento verticale impostato su |
Risultato |
|
|
Per FlowColumn
sono disponibili opzioni simili. L'allineamento predefinito è Alignment.Start
.
Numero massimo di elementi in una riga o colonna
I parametri maxItemsInEachRow
o maxItemsInEachColumn
definiscono il numero massimo di elementi
nell'asse principale da consentire di inserire una riga prima di eseguire il wrapping a quella successiva. Il valore predefinito è Int.MAX_INT
, che consente il maggior numero possibile di elementi, a condizione che le loro dimensioni ne permettano l'inserimento nella riga.
Ad esempio, l'impostazione di un maxItemsInEachRow
impone al layout iniziale di includere solo 3 elementi:
Nessun valore massimo impostato |
|
Elementi del flusso di caricamento lento
ContextualFlowRow
e ContextualFlowColumn
sono una versione specializzata di FlowRow
e FlowColumn
che ti consente di caricare tramite caricamento lento i contenuti della riga o della colonna del flusso. Forniscono inoltre informazioni sulla posizione degli elementi (indice, numero di riga e dimensione disponibile), ad esempio se l'elemento si trova nella prima riga. Questo è utile per set di dati di grandi dimensioni e se hai bisogno di informazioni contestuali
su un elemento.
Il parametro maxLines
limita il numero di righe visualizzate, mentre il parametro overflow
specifica cosa visualizzare quando viene raggiunto un overflow di elementi, consentendoti di specificare un valore expandIndicator
o collapseIndicator
personalizzato.
Ad esempio, per mostrare un pulsante "+ (numero di elementi rimanenti)" o "Mostra meno":
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") }
Ponderazioni degli articoli
La ponderazione di un elemento aumenta in base al fattore e allo spazio disponibile sulla riga in cui è stato posizionato. È importante sottolineare che c'è una differenza tra FlowRow
e Row
nel modo in cui le ponderazioni vengono utilizzate per calcolare la larghezza di un elemento. Per Rows
, il peso
si basa su tutti gli articoli della categoria Row
. Con FlowRow
, la ponderazione si basa sugli
elementi nella riga in cui è inserito un elemento, non su tutti gli elementi contenuti
nel contenitore FlowRow
.
Ad esempio, se disponi di quattro elementi che rientrano tutti su una riga, ciascuno con ponderazioni diverse di 1f, 2f, 1f
e 3f
, la ponderazione totale è 7f
. Lo spazio rimanente in una riga o in una colonna verrà diviso per 7f
. Quindi, la larghezza di ogni elemento verrà calcolata utilizzando: weight * (remainingSpace / totalWeight)
.
Puoi utilizzare una combinazione di Modifier.weight
e del numero massimo di elementi con FlowRow
o FlowColumn
per creare un layout di griglia. Questo approccio è utile per creare layout adattabili che si adattano alle dimensioni del dispositivo.
Esistono diversi esempi di obiettivi che puoi ottenere utilizzando le ponderazioni. Un esempio è una griglia in cui gli elementi hanno le stesse dimensioni, come mostrato di seguito:
Per creare una griglia di dimensioni uguali per gli articoli:
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 sottolineare che, se aggiungi un altro elemento e lo ripeti 10 volte invece di 9, l'ultimo elemento occupa l'intera ultima colonna, poiché il peso totale dell'intera riga è 1f
:
Puoi combinare le ponderazioni con altri Modifiers
, ad esempio
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
o
Modifier.fillMaxWidth(fraction)
. Questi modificatori funzionano tutti insieme per
consentire il dimensionamento adattabile degli elementi in un elemento FlowRow
(o FlowColumn
).
Puoi anche creare una griglia alternativa di dimensioni diverse degli elementi, in cui due elementi occupano metà della larghezza ciascuno e un elemento occupa l'intera larghezza della colonna successiva:
Puoi ottenere questo risultato con il seguente codice:
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)) } } }
Dimensioni frazionarie
Con Modifier.fillMaxWidth(fraction)
, puoi specificare le dimensioni del
contenitore che deve occupare un elemento. Questo è diverso da come
Modifier.fillMaxWidth(fraction)
funziona quando viene applicato a Row
o Column
, in quanto Row/Column
elementi occupano una percentuale della larghezza rimanente, anziché
la larghezza dell'intero contenitore.
Ad esempio, il codice seguente produce risultati diversi quando utilizzi FlowRow
rispetto a 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()
L'applicazione di Modifier.fillMaxColumnWidth()
o
Modifier.fillMaxRowHeight()
a un elemento all'interno di un elemento FlowColumn
o FlowRow
garantisce che gli elementi nella stessa colonna o riga abbiano la stessa larghezza o altezza
dell'elemento più grande nella colonna/riga.
Ad esempio, in questo esempio viene utilizzato FlowColumn
per visualizzare l'elenco di dolci Android. Puoi vedere la differenza nelle larghezze di ogni elemento quando
Modifier.fillMaxColumnWidth()
viene applicato agli elementi rispetto a quando non è applicato e
l'elemento è a capo.
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) ) } } }
Valore |
|
Nessuna modifica alla larghezza impostata (elementi a capo) |
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Nozioni di base sul layout di scrittura
- Vincolo Layout in Compose
- Azioni dell'editor {:#editor-actions}