Прокрутка или скроллинг представляет движение пальцем по вертикали или по горизонтали. Ранее мы уже рассматривали прокрутку в статье Создание прокрутки,
в частности, мы рассматривали, как с помощью модификаторов horizontalScroll()
и verticalScroll()
можно определить прокрутку соответственно по горизонтали и вертикали. Благодаря этим модификаторам
нам не надо думать о реализации логики прокрутки, все делеается автоматически. Тем не менее мы можем задать и свою собственную логику прокрутки, применяя модификатор scrollable().
Для управления прокруткой применяется состояние, которое создается с помощью функции rememberScrollableState(). В нее передается функция, которая дает нам доступ к расстоянию, пройденному жестом прокрутки. Данное расстояние можно использовать для регулировки смещения одного или нескольких компонентов на экране. Например:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.rememberScrollableState import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import kotlin.math.roundToInt class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { var offset by remember { mutableStateOf(0f) } Box(Modifier .fillMaxSize() .scrollable( orientation = Orientation.Vertical, state = rememberScrollableState { distance -> offset += distance distance } ) ) { Box(Modifier .size(150.dp) .padding(10.dp) .offset { IntOffset(0, offset.roundToInt()) } .background(Color.DarkGray)) } } } }
В данном случае мы управляем прокруткой внутри элемента Box, который занимает всю поверхность экрана. Для отслеживания позиции прокрутки устанавливается переменная offset.
var offset by remember { mutableStateOf(0f) }
В компоненте Box применяем модификатор scrollable():
.scrollable( orientation = Orientation.Vertical, state = rememberScrollableState { distance -> offset += distance distance } )
В rememberScrollableState
передается функция, которая определяет параметр distanse. Этот параметр представляет объект Offset, из которого мы можем получить последние значения
смещения при прокрутке. Затем это смещение добавляется к состоянияю offset.
Вложенный компонент Box, который представляет темно-серый квадрат размером 150х150, использует значение offset для установки положения по оси y
Box(Modifier .size(150.dp) .padding(10.dp) .offset { IntOffset(0, offset.roundToInt()) } .background(Color.DarkGray))
Таким образом, при прокрутке будет изменяться позиция вложенного компонента Box: