Modyfikatory przewijania
Modyfikatory
verticalScroll
i
horizontalScroll
to najprostszy sposób, aby umożliwić użytkownikowi przewijanie elementu, gdy granice jego zawartości są większe niż ograniczenia maksymalnego rozmiaru. Modyfikatory verticalScroll i horizontalScroll nie wymagają tłumaczenia ani przesuwania treści.
@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 umożliwia zmianę pozycji przewijania lub uzyskanie jej bieżącego stanu. Aby utworzyć go z parametrami domyślnymi, użyj polecenia 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)) } } }
Modyfikator obszaru przewijania
Modyfikator scrollableArea jest podstawowym elementem składowym tworzenia niestandardowych kontenerów z możliwością przewijania. Zapewnia wyższy poziom abstrakcji w stosunku do modyfikatora scrollable, obsługując typowe wymagania, takie jak interpretacja delty gestu, przycinanie treści i efekty przewijania.
Chociaż scrollableArea jest używane w przypadku implementacji niestandardowych, w przypadku standardowych list przewijanych zwykle lepiej jest używać gotowych rozwiązań, takich jak verticalScroll, horizontalScroll lub komponentów kompozycyjnych, takich jak LazyColumn. Te komponenty wyższego poziomu są prostsze w przypadku typowych zastosowań i są tworzone przy użyciu scrollableArea.
Różnica między modyfikatorami scrollableArea i scrollable
Główna różnica między scrollableArea a scrollable polega na tym, jak interpretują one gesty przewijania użytkownika:
scrollable(surowa wartość delta): wartość delta bezpośrednio odzwierciedla fizyczny ruch danych wejściowych użytkownika (np. przeciągnięcie wskaźnika) na ekranie.scrollableArea(delta zorientowana na treść): symboldeltajest semantycznie odwrócony, aby odzwierciedlać wybraną zmianę pozycji przewijania, dzięki czemu treść wydaje się poruszać wraz z gestem użytkownika, co zwykle jest odwrotnością ruchu wskaźnika.
Wyobraź sobie, że scrollable informuje o tym, jak porusza się wskaźnik, a scrollableArea przekłada ten ruch na to, jak treści powinny się poruszać w typowym widoku z możliwością przewijania. Ta inwersja sprawia, że scrollableArea
jest bardziej naturalne podczas wdrażania standardowego kontenera z możliwością przewijania.
W tabeli poniżej znajdziesz podsumowanie znaków delta w przypadku typowych scenariuszy:
Gest użytkownika |
Zmiana zgłoszona do |
zmiana zgłoszona do |
|---|---|---|
Wskaźnik przesuwa się W GÓRĘ |
Negatywna |
Pozytywny |
Wskaźnik przesuwa się W DÓŁ |
Pozytywny |
Negatywna |
Wskaźnik przesuwa się w LEWO. |
Negatywna |
Dodatnia (ujemna w przypadku języków pisanych od prawej do lewej) |
Wskaźnik przesuwa się W PRAWO |
Pozytywny |
Negatywny (pozytywny w przypadku języków zapisywanych od prawej do lewej) |
(*) Uwaga dotycząca scrollableArea znaku delty: znak delty od scrollableArea nie jest prostym odwróceniem. Inteligentnie uwzględnia:
- Orientacja: pionowa lub pozioma.
LayoutDirection: od lewej do prawej lub od prawej do lewej (szczególnie ważne w przypadku przewijania w poziomie).- Flaga
reverseScrolling: określa, czy kierunek przewijania jest odwrócony.
Oprócz odwracania delty przewijania scrollableArea przycina też treść do granic układu i obsługuje renderowanie efektów przewijania poza zakres. Domyślnie używa efektu zapewnianego przez LocalOverscrollFactory.
Możesz dostosować lub wyłączyć tę funkcję, używając przeciążenia scrollableArea, które akceptuje parametr OverscrollEffect.
Kiedy używać modyfikatora scrollableArea
Modyfikatora scrollableArea należy używać, gdy chcesz utworzyć niestandardowy komponent przewijania, który nie jest odpowiednio obsługiwany przez modyfikatory horizontalScroll lub verticalScroll ani przez układy leniwe. Często dotyczy to przypadków:
- Niestandardowa logika układu: gdy układ elementów zmienia się dynamicznie w zależności od pozycji przewijania.
- Unikalne efekty wizualne: stosowanie przekształceń, skalowania lub innych efektów podczas przewijania treści z dziećmi.
- Bezpośrednia kontrola: potrzebujesz precyzyjnej kontroli nad mechanizmem przewijania, która wykracza poza możliwości
verticalScrolllub układów leniwych.
Tworzenie niestandardowych list w formie koła za pomocą symbolu scrollableArea
Ten przykład pokazuje, jak za pomocą parametru scrollableArea utworzyć niestandardową listę pionową, na której elementy zmniejszają się w miarę oddalania się od środka, co daje efekt wizualny przypominający koło. Tego rodzaju przekształcenie zależne od przewijania jest idealnym przykładem zastosowania 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 } } } } // ...
Modyfikator z możliwością przewijania
Modyfikator
scrollable
różni się od modyfikatorów przewijania tym, że scrollable wykrywa gesty przewijania i rejestruje zmiany, ale nie przesuwa automatycznie zawartości. Zamiast tego uprawnienia są delegowane na użytkownika za pomocą
ScrollableState
, co jest wymagane do prawidłowego działania tego modyfikatora.
Podczas tworzenia funkcji ScrollableState musisz podać funkcję consumeScrollDelta, która będzie wywoływana przy każdym kroku przewijania (za pomocą gestu, płynnego przewijania lub szybkiego przewijania) z wartością delta w pikselach. Ta funkcja musi zwracać ilość przewiniętej odległości, aby zdarzenie było prawidłowo propagowane w przypadku elementów zagnieżdżonych, które mają modyfikator scrollable.
Poniższy fragment kodu wykrywa gesty i wyświetla wartość liczbową przesunięcia, ale nie przesuwa żadnych elementów:
@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()) } }
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy język JavaScript jest wyłączony.
- Informacje o gestach
- Migracja z
CoordinatorLayoutdo Compose - Używanie widoków w Compose