Modificatori di scorrimento
I modificatori
verticalScroll
e
horizontalScroll
offrono il modo più semplice per consentire all'utente di scorrere un elemento quando
i limiti dei suoi contenuti sono maggiori dei vincoli di dimensione massima. Con i modificatori verticalScroll e horizontalScroll non è necessario tradurre o compensare i contenuti.
@Composable private fun ScrollBoxes() { Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .verticalScroll(rememberScrollState()) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
ScrollState
consente di modificare la posizione di scorrimento o ottenere il suo stato attuale. Per crearlo
con i parametri predefiniti, utilizza
rememberScrollState().
@Composable private fun ScrollBoxesSmooth() { // Smoothly scroll 100px on first composition val state = rememberScrollState() LaunchedEffect(Unit) { state.animateScrollTo(100) } Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .padding(horizontal = 8.dp) .verticalScroll(state) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
Modificatore dell'area scorrevole
Il modificatore scrollableArea è un elemento costitutivo fondamentale per la creazione di
contenitori scorrevoli personalizzati. Fornisce un'astrazione di livello superiore rispetto al modificatore
scrollable, gestendo requisiti comuni come l'interpretazione del delta dei gesti, il ritaglio dei contenuti e gli effetti di overscroll.
Sebbene scrollableArea venga utilizzato per implementazioni personalizzate, in genere dovresti preferire soluzioni pronte all'uso come verticalScroll, horizontalScroll o componibili come LazyColumn per elenchi di scorrimento standard. Questi
componenti di livello superiore sono più semplici per i casi d'uso comuni e sono
costruiti utilizzando scrollableArea.
Differenza tra i modificatori scrollableArea e scrollable
La differenza principale tra scrollableArea e scrollable risiede nel modo in cui interpretano i gesti di scorrimento dell'utente:
scrollable(delta grezzo): il delta riflette direttamente il movimento fisico dell'input dell'utente (ad es. trascinamento del puntatore) sullo schermo.scrollableArea(delta orientato ai contenuti): ildeltaè invertito semanticamente per rappresentare la variazione selezionata nella posizione di scorrimento in modo che i contenuti sembrino muoversi con il gesto dell'utente, che di solito è l'opposto del movimento del puntatore.
Immagina che scrollable ti dica come si è spostato il puntatore, mentre
scrollableArea traduce il movimento del puntatore in come i contenuti devono
muoversi all'interno di una tipica visualizzazione scorrevole. Questa inversione è il motivo per cui scrollableArea
risulta più naturale quando si implementa un contenitore scorrevole standard.
La tabella seguente riepiloga i segni di variazione per gli scenari comuni:
Attivazione dall'utente |
delta segnalato a |
delta segnalato a |
|---|---|---|
Il puntatore si sposta VERSO L'ALTO |
Negativo |
Positivo |
Il puntatore si sposta IN BASSO |
Positivo |
Negativo |
Il puntatore si sposta a SINISTRA |
Negativo |
Positivo (Negativo per RTL) |
Il puntatore si sposta a DESTRA |
Positivo |
Negativo (positivo per RTL) |
(*) Nota sul segno delta scrollableArea: il segno del delta da
scrollableArea non è una semplice inversione. Prende in considerazione in modo intelligente:
- Orientamento: verticale o orizzontale.
LayoutDirection: da sinistra a destra o da destra a sinistra (particolarmente importante per lo scorrimento orizzontale).- Flag
reverseScrolling: indica se la direzione di scorrimento è invertita.
Oltre a invertire il delta di scorrimento, scrollableArea ritaglia anche i contenuti in base ai limiti del layout e gestisce il rendering degli effetti di overscroll. Per impostazione predefinita, utilizza l'effetto fornito da LocalOverscrollFactory.
Puoi personalizzare o disattivare questa funzionalità utilizzando l'overload scrollableArea
che accetta un parametro OverscrollEffect.
Quando utilizzare il modificatore scrollableArea
Devi utilizzare il modificatore scrollableArea quando devi creare un componente di scorrimento personalizzato che non viene gestito in modo adeguato dai modificatori horizontalScroll o verticalScroll o dai layout pigri. Spesso si tratta di casi con:
- Logica di layout personalizzata: quando la disposizione degli elementi cambia dinamicamente in base alla posizione di scorrimento.
- Effetti visivi unici: applicazione di trasformazioni, ridimensionamenti o altri effetti ai bambini mentre scorrono.
- Controllo diretto: necessità di un controllo granulare sui meccanismi di scorrimento
oltre a quanto esposto da
verticalScrollo dai layout pigri.
Creare elenchi personalizzati a forma di ruota utilizzando scrollableArea
Il seguente esempio mostra l'utilizzo di scrollableArea per creare un elenco verticale personalizzato in cui gli elementi vengono ridimensionati man mano che si allontanano dal centro, creando un effetto visivo simile a una ruota. Questo tipo di trasformazione dipendente dallo scorrimento è un
caso d'uso perfetto per scrollableArea.
scrollableArea.
@Composable private fun ScrollableAreaSample() { // ... Layout( modifier = Modifier .size(150.dp) .scrollableArea(scrollState, Orientation.Vertical) .background(Color.LightGray), // ... ) { measurables, constraints -> // ... // Update the maximum scroll value to not scroll beyond limits and stop when scroll // reaches the end. scrollState.maxValue = (totalHeight - viewportHeight).coerceAtLeast(0) // Position the children within the layout. layout(constraints.maxWidth, viewportHeight) { // The current vertical scroll position, in pixels. val scrollY = scrollState.value val viewportCenterY = scrollY + viewportHeight / 2 var placeableLayoutPositionY = 0 placeables.forEach { placeable -> // This sample applies a scaling effect to items based on their distance // from the center, creating a wheel-like effect. // ... // Place the item horizontally centered with a layer transformation for // scaling to achieve wheel-like effect. placeable.placeRelativeWithLayer( x = constraints.maxWidth / 2 - placeable.width / 2, // Offset y by the scroll position to make placeable visible in the viewport. y = placeableLayoutPositionY - scrollY, ) { scaleX = scaleFactor scaleY = scaleFactor } // Move to the next item's vertical position. placeableLayoutPositionY += placeable.height } } } } // ...
Modificatore scorrevole
Il modificatore
scrollable
è diverso dai modificatori di scorrimento in quanto scrollable rileva i
gesti di scorrimento e acquisisce i delta, ma non compensa automaticamente i contenuti. Questa operazione viene invece delegata all'utente tramite
ScrollableState
, che è necessaria per il corretto funzionamento di questo modificatore.
Quando crei ScrollableState, devi fornire una funzione consumeScrollDelta
che verrà richiamata a ogni passaggio di scorrimento (tramite input tramite gesto, scorrimento
fluido o scorrimento rapido) con il delta in pixel. Questa funzione deve restituire la
quantità di distanza di scorrimento consumata, per garantire che l'evento venga propagato correttamente nei casi in cui sono presenti elementi nidificati con il modificatore scrollable.
Il seguente snippet rileva i gesti e mostra un valore numerico per un offset, ma non sposta alcun elemento:
@Composable private fun ScrollableSample() { // actual composable state var offset by remember { mutableFloatStateOf(0f) } Box( Modifier .size(150.dp) .scrollable( orientation = Orientation.Vertical, // Scrollable state: describes how to consume // scrolling delta and update offset state = rememberScrollableState { delta -> offset += delta delta } ) .background(Color.LightGray), contentAlignment = Alignment.Center ) { Text(offset.toString()) } }
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Informazioni sui gesti
- Eseguire la migrazione di
CoordinatorLayouta Compose - Utilizzare le visualizzazioni in Compose