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. W przypadku modyfikatorów verticalScroll i horizontalScroll nie musisz tłumaczyć ani przesuwać 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 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 służącym do tworzenia niestandardowych kontenerów z możliwością przewijania. Zapewnia wyższy poziom abstrakcji niż modyfikator scrollable, obsługując typowe wymagania, takie jak interpretacja delty gestu, przycinanie treści i efekty przewijania poza zakres.
Chociaż scrollableArea jest używane w przypadku niestandardowych implementacji, w przypadku standardowych list przewijanych zwykle lepiej jest używać gotowych rozwiązań, takich jak verticalScroll, horizontalScroll lub komponentów kompozycyjnych, np. 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 zapisywanych 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 delta: znak delty od scrollableArea nie jest tylko 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 dostarczonego 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, w których:
- 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 w przypadku dzieci podczas przewijania.
- Bezpośrednia kontrola: potrzebujesz precyzyjnej kontroli nad mechanizmami 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 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 zagnieżdżonych elementów, 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