Модификаторы прокрутки
Модификаторы verticalScroll и horizontalScroll предоставляют самый простой способ позволить пользователю прокручивать элемент, когда границы его содержимого превышают его максимальный размер. С модификаторами verticalScroll и horizontalScroll вам не нужно перемещать или смещать содержимое.
@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 позволяет изменять положение прокрутки или получать её текущее состояние. Для создания объекта с параметрами по умолчанию используйте 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)) } } }
Модификатор прокручиваемой области
Модификатор scrollableArea — это фундаментальный строительный блок для создания пользовательских прокручиваемых контейнеров. Он обеспечивает более высокий уровень абстракции над модификатором scrollable , обрабатывая общие требования, такие как интерпретация изменений жестов, обрезка контента и эффекты перепрокрутки.
Хотя scrollableArea используется для пользовательских реализаций, для стандартных списков с прокруткой, как правило, следует отдавать предпочтение готовым решениям, таким как verticalScroll , horizontalScroll или компонуемым компонентам, например LazyColumn . Эти высокоуровневые компоненты проще для распространенных случаев использования и сами создаются с помощью scrollableArea .
Разница между модификаторами scrollableArea и scrollable
Основное различие между scrollableArea и scrollable заключается в том, как они интерпретируют жесты прокрутки пользователя:
-
scrollable(необработанное значение дельты): Дельта напрямую отражает физическое перемещение ввода пользователя (например, перетаскивание указателя) по экрану. -
scrollableArea(содержимое-ориентированная дельта):deltaсемантически инвертируется, чтобы представить выбранное изменение положения прокрутки, благодаря чему содержимое будет выглядеть перемещающимся в соответствии с жестом пользователя, который обычно противоположен движению указателя.
Представьте себе это так: scrollable показывает, как перемещался указатель мыши, а scrollableArea преобразует это перемещение указателя в то, как должно перемещаться содержимое в типичном прокручиваемом представлении. Именно эта инверсия объясняет, почему scrollableArea кажется более естественным при реализации стандартного прокручиваемого контейнера.
В следующей таблице приведено краткое описание знаков дельты для распространенных сценариев:
Жест пользователя | Дельта, передаваемая в | delta сообщается в |
|---|---|---|
Указатель движется ВВЕРХ | Отрицательный | Положительный |
Указатель движется ВНИЗ | Положительный | Отрицательный |
Указатель перемещается влево. | Отрицательный | Положительный результат (отрицательный результат для RTL) |
Указатель движется ВПРАВО | Положительный | Отрицательный результат (положительный результат для RTL) |
(*) Примечание о знаке дельты scrollableArea : Знак дельты от scrollableArea не является простой инверсией. Он учитывает следующее:
- Ориентация : вертикальная или горизонтальная.
-
LayoutDirection: LTR или RTL (особенно важно для горизонтальной прокрутки). - флаг
reverseScrolling: Указывает, инвертируется ли направление прокрутки.
Помимо инвертирования дельты прокрутки, scrollableArea также обрезает содержимое по границам макета и обрабатывает рендеринг эффектов перепрокрутки. По умолчанию используется эффект, предоставляемый LocalOverscrollFactory . Вы можете настроить или отключить это, используя перегрузку scrollableArea , которая принимает параметр OverscrollEffect .
Когда использовать модификатор scrollableArea
Модификатор scrollableArea следует использовать, когда необходимо создать собственный компонент прокрутки, для которого недостаточно подходят модификаторы horizontalScroll , verticalScroll или Lazy layouts. Это часто связано со следующими случаями:
- Настраиваемая логика компоновки : когда расположение элементов динамически изменяется в зависимости от положения прокрутки.
- Уникальные визуальные эффекты : применение преобразований, масштабирования или других эффектов к элементам интерфейса при прокрутке.
- Прямое управление : Требуется точный контроль над механикой прокрутки, выходящий за рамки возможностей
verticalScrollили отложенной компоновки.
Создавайте пользовательские списки в виде колеса с помощью scrollableArea
В следующем примере показано, как использовать scrollableArea для создания пользовательского вертикального списка, в котором элементы уменьшаются по мере удаления от центра, создавая визуальный эффект «колеса». Такое преобразование, зависящее от прокрутки, идеально подходит для использования 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 } } } } // ...
Прокручиваемый модификатор
Модификатор scrollable отличается от модификаторов scroll тем, что scrollable отслеживает жесты прокрутки и фиксирует изменения, но не смещает содержимое автоматически. Вместо этого эта функция передается пользователю через ScrollableState , который необходим для корректной работы этого модификатора.
При создании ScrollableState необходимо указать функцию consumeScrollDelta , которая будет вызываться на каждом шаге прокрутки (при вводе жеста, плавной прокрутке или перемещении курсора) с изменением расстояния в пикселях. Эта функция должна возвращать величину пройденного расстояния прокрутки, чтобы обеспечить корректное распространение события в случаях, когда имеются вложенные элементы с модификатором scrollable .
Приведенный ниже фрагмент кода распознает жесты и отображает числовое значение смещения, но не смещает никакие элементы:
@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()) } }

Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Понимать жесты
- Перенести
CoordinatorLayoutв Compose - Использование представлений в Compose