Les modificateurs verticalScroll et horizontalScroll sont la solution la plus simple pour autoriser l'utilisateur à faire défiler un élément lorsque les limites de son contenu dépassent les contraintes de taille maximales. Avec les modificateurs verticalScroll et horizontalScroll, vous n'avez pas besoin de décaler le contenu ni d'effectuer une translation.
@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)) } } }
Le ScrollState vous permet de modifier la position de défilement ou d'obtenir son état actuel. Pour le créer avec des paramètres par défaut, utilisez 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)) } } }
Modificateur de zone de défilement
Le modificateur scrollableArea est un composant fondamental pour créer des conteneurs personnalisés à faire défiler. Il fournit une abstraction de niveau supérieur par rapport au modificateur scrollable, en gérant les exigences courantes telles que l'interprétation du delta des gestes, le découpage du contenu et les effets de défilement au-delà des limites.
Bien que scrollableArea soit utilisé pour les implémentations personnalisées, vous devriez généralement privilégier les solutions prêtes à l'emploi telles que verticalScroll, horizontalScroll ou des composables tels que LazyColumn pour les listes déroulantes standards. Ces composants de niveau supérieur sont plus simples pour les cas d'utilisation courants et sont eux-mêmes créés à l'aide de scrollableArea.
Différence entre les modificateurs scrollableArea et scrollable
La principale différence entre scrollableArea et scrollable réside dans la façon dont ils interprètent les gestes de défilement de l'utilisateur :
scrollable(delta brut) : le delta reflète directement le mouvement physique de l'entrée de l'utilisateur (par exemple, le déplacement du pointeur) sur l'écran.scrollableArea(delta orienté contenu) : ledeltaest inversé sémantiquement pour représenter la modification sélectionnée de la position de défilement afin que le contenu semble se déplacer avec le geste de l'utilisateur, qui est généralement l'opposé du mouvement du pointeur.
En d'autres termes, scrollable vous indique comment le pointeur s'est déplacé, tandis que scrollableArea traduit ce mouvement du pointeur en mouvement du contenu dans une vue déroulante standard. Cette inversion explique pourquoi scrollableArea semble plus naturel lors de l'implémentation d'un conteneur déroulant standard.
Le tableau suivant récapitule les signes delta pour les scénarios courants :
Geste de l'utilisateur |
delta signalé à |
delta signalé à |
|---|---|---|
Le pointeur se déplace vers le HAUT. |
Négatif |
Positif |
Le pointeur se déplace vers le BAS |
Positif |
Négatif |
Le pointeur se déplace vers la GAUCHE. |
Négatif |
Positive (Negative pour RTL) |
Le pointeur se déplace vers la DROITE |
Positif |
Négatif (positif pour les langues s'écrivant de droite à gauche) |
(*) Remarque sur le signe delta scrollableArea : le signe du delta de scrollableArea n'est pas une simple inversion. Il prend intelligemment en compte :
- Orientation : verticale ou horizontale.
LayoutDirection: de gauche à droite ou de droite à gauche (particulièrement important pour le défilement horizontal).- Indicateur
reverseScrolling: indique si le sens de défilement est inversé.
En plus d'inverser le delta de défilement, scrollableArea limite également le contenu aux limites de la mise en page et gère l'affichage des effets de défilement hors limites. Par défaut, il utilise l'effet fourni par LocalOverscrollFactory.
Vous pouvez personnaliser ou désactiver cette option en utilisant la surcharge scrollableArea qui accepte un paramètre OverscrollEffect.
Quand utiliser le modificateur scrollableArea ?
Vous devez utiliser le modificateur scrollableArea lorsque vous devez créer un composant de défilement personnalisé qui n'est pas correctement géré par les modificateurs horizontalScroll ou verticalScroll, ou par les mises en page différées. Cela implique souvent des cas avec :
- Logique de mise en page personnalisée : lorsque la disposition des éléments change de manière dynamique en fonction de la position de défilement.
- Effets visuels uniques : application de transformations, de mise à l'échelle ou d'autres effets aux enfants lorsqu'ils font défiler l'écran.
- Contrôle direct : vous avez besoin d'un contrôle précis des mécanismes de défilement au-delà de ce que
verticalScrollou les mises en page différées exposent.
Créez des listes personnalisées de type roue à l'aide de scrollableArea
L'exemple suivant montre comment utiliser scrollableArea pour créer une liste verticale personnalisée dans laquelle les éléments sont réduits à mesure qu'ils s'éloignent du centre, créant ainsi un effet visuel de "roue". Ce type de transformation dépendant du défilement est un cas d'utilisation idéal pour 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 } } } } // ...
Modificateur Scrollable
Le modificateur scrollable diffère des modificateurs Scroll dans le sens où scrollable détecte les gestes de défilement et capture les deltas, mais ne décale pas son contenu automatiquement. Cette tâche est déléguée à l'utilisateur via ScrollableState, qui est nécessaire pour que ce modificateur fonctionne correctement.
Lorsque vous construisez ScrollableState, vous devez fournir une fonction consumeScrollDelta qui sera appelée à chaque étape de défilement (par saisie gestuelle, défilement fluide ou glissement d'un geste vif) avec le delta en pixels. Cette fonction doit renvoyer la distance de défilement consommée, pour garantir que l'événement se propage correctement dans les cas où des éléments imbriqués disposent du modificateur scrollable.
L'extrait de code suivant détecte les gestes et affiche une valeur numérique correspondant à un décalage, mais ne décale aucun élément :
@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()) } }
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Comprendre les gestes
- Migrer
CoordinatorLayoutvers Compose - Utiliser les vues dans Compose