Есть ли способ заставить работать синхронно два горизонтальных пейджера библиотеки концертмейстеров?
Я пытаюсь добиться, если есть два горизонтальных пейджера, а затем, проведя пальцем по верхнему левому, нижний горизонтальный пейджер должен провести вправо и наоборот, попытался использовать метод pagerState scrollBy, но не получил желаемого результата
1 ответ
В первую очередь нужно определить, какой пейджер прокручивается, а какой должен следовать за ним. Это можно сделать с
isScrollInProgress
, я использую его внутри
derivedStateOf
чтобы избежать ненужных повторных композиций.
Тогда я бегу. Я передаю пару состояний пейджера в нужном порядке или нуль, как
key
, так
LaunchedEffect
будет перезапущен при остановке/начале прокрутки. С использованием
snapshotFlow
, можно отслеживать изменения результата блока, вычисления которого зависят от изменения состояния.
PagerState
имеет информацию о положении прокрутки в свойствах
currentPage
а также .
scrollToPage
берет только
0..1
значения смещения страницы, но
currentPageOffset
может быть меньше нуля при прокрутке назад.
Предполагать
currentPage = 2
а также
currentPageOffset = -0.1
. В этом случае я получу
1.9
в
pagePart
, и мне нужно разделить его, чтобы получить
1
а также
0.9
. Для этого я использую
divideAndRemainder
: он вернет список формы
listOf(1.0, 0.9)
.
Column {
val count = 10
val firstPagerState = rememberPagerState()
val secondPagerState = rememberPagerState()
val scrollingFollowingPair by remember {
derivedStateOf {
if (firstPagerState.isScrollInProgress) {
firstPagerState to secondPagerState
} else if (secondPagerState.isScrollInProgress) {
secondPagerState to firstPagerState
} else null
}
}
LaunchedEffect(scrollingFollowingPair) {
val (scrollingState, followingState) = scrollingFollowingPair ?: return@LaunchedEffect
snapshotFlow { scrollingState.currentPage + scrollingState.currentPageOffset }
.collect { pagePart ->
val divideAndRemainder = BigDecimal.valueOf(pagePart.toDouble())
.divideAndRemainder(BigDecimal.ONE)
followingState.scrollToPage(
divideAndRemainder[0].toInt(),
divideAndRemainder[1].toFloat(),
)
}
}
HorizontalPager(
count = count,
state = firstPagerState,
modifier = Modifier.weight(1f)
) {
Text(it.toString())
}
HorizontalPager(
count = count,
state = secondPagerState,
modifier = Modifier.weight(1f)
) {
Text(it.toString())
}
}
Результат: