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 traslare 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 di ottenere lo stato corrente. 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 di base fondamentale per la creazione di container 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 le implementazioni personalizzate, in genere dovresti preferire soluzioni pronte all'uso come verticalScroll, horizontalScroll o componibili come LazyColumn per gli elenchi a scorrimento standard. Questi componenti di livello superiore sono più semplici per i casi d'uso comuni e sono a loro volta creati 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 non elaborato): il delta riflette direttamente il movimento fisico dell'input dell'utente (ad es. il trascinamento del puntatore) sullo schermo.scrollableArea(delta orientato ai contenuti):deltaviene invertito semanticamente per rappresentare la variazione selezionata nella posizione di scorrimento per far sembrare che i contenuti si muovano con il gesto dell'utente, che di solito è l'opposto del movimento del cursore.
Pensa a questo: scrollable ti dice come si è spostato il puntatore, mentre scrollableArea traduce questo movimento del puntatore in come i contenuti dovrebbero spostarsi all'interno di una tipica visualizzazione scorrevole. Questa inversione è il motivo per cui scrollableArea
sembra più naturale quando si implementa un contenitore scorrevole standard.
La tabella seguente riassume i segni delta per gli scenari comuni:
Attivazione dall'utente |
delta segnalato a |
delta segnalato a |
|---|---|---|
Il puntatore si sposta VERSO L'ALTO |
Negative |
Positive |
Il puntatore si sposta IN BASSO |
Positive |
Negative |
Il puntatore si sposta a SINISTRA |
Negative |
Positive (Negative per RTL) |
Il puntatore si sposta a DESTRA |
Positive |
Negativo (positivo per RTL) |
(*) Nota sul segno delta di scrollableArea: il segno del delta di scrollableArea non è una semplice inversione. Tiene conto in modo intelligente di:
- Orientamento: verticale o orizzontale.
LayoutDirection: LTR o RTL (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 opzione 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 è supportato adeguatamente dai modificatori horizontalScroll o verticalScroll o dai layout con caricamento lento. Spesso si tratta di casi con:
- Logica di layout personalizzata: quando la disposizione degli elementi cambia in modo dinamico in base alla posizione di scorrimento.
- Effetti visivi unici: applicazione di trasformazioni, ridimensionamento o altri effetti agli elementi secondari durante lo scorrimento.
- Controllo diretto: se hai bisogno di un controllo granulare sui meccanismi di scorrimento oltre a quello offerto da
verticalScrollo dai layout lazy.
Crea elenchi personalizzati simili a ruote utilizzando scrollableArea
L'esempio seguente mostra l'utilizzo di scrollableArea per creare un elenco verticale personalizzato in cui gli elementi vengono ridotti man mano che si allontanano dal centro, creando un effetto visivo "a 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 è necessario per il corretto funzionamento di questo modificatore.
Quando crei ScrollableState, devi fornire una funzione consumeScrollDelta che verrà richiamata in ogni passaggio di scorrimento (tramite input di gesti, scorrimento fluido o scorrimento veloce) 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 siano presenti elementi nidificati con il modificatore scrollable.
Il seguente snippet rileva i gesti e visualizza un valore numerico per un offset, ma non compensa 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
- Esegui la migrazione di
CoordinatorLayouta Compose - Utilizzo delle visualizzazioni in Compose