Reputation: 471
I have a LazyColumn
inside a HorizontalPager
which lets me have different pages where each one is scrollable. This is for a calendar app that has a page for each day.
HorizontalPager(state = pagerState) { index->
LazyColumn {
<...content here...>
}
}
But I'm not sure how to sync the scroll state between pages. Currently if I scroll to halfway down the first page and swipe to the next, it starts at the top again.
How would I have all pages keep the same scroll?
Upvotes: 3
Views: 498
Reputation: 10777
Unfortunately, it seems not to be very easy to get this functionality to work. Each LazyColumn
must have its own LazyListState
, thus you can't just assign a single one to all LazyColumn
s.
So you would need some logic to manually synchronize them and store a separate global scroll state.
I wrote the following code, which however has the drawback that under certain situations, when you swipe the HorizontalPager
while the LazyColumn
is still scrolling, the scroll state sometimes is not correctly applied.
You can test it and see whether it is acceptable in your case. Unfortunately, I wasn't able to track down the actual issue. It seems that scrollToItem
sometimes is blocking until you swipe to that page, and then the scroll is not correctly applied.
However, here is my code:
val pagerState = rememberPagerState(pageCount = { 3 })
var firstVisibleItemIndex by remember{
mutableIntStateOf(0)
}
var firstVisibleItemScrollOffset by remember {
mutableIntStateOf(0)
}
HorizontalPager(state = pagerState) { thisPage ->
val localScrollState = rememberLazyListState()
var wasScrolled by remember { mutableStateOf(false) }
LaunchedEffect(firstVisibleItemIndex, firstVisibleItemScrollOffset) {
// apply global scroll state
wasScrolled = false
localScrollState.scrollToItem(firstVisibleItemIndex, firstVisibleItemScrollOffset)
}
LaunchedEffect(localScrollState.isScrollInProgress) {
if (localScrollState.isScrollInProgress) {
wasScrolled = true
} else if (wasScrolled) {
// write to global scroll state
firstVisibleItemIndex = localScrollState.firstVisibleItemIndex
firstVisibleItemScrollOffset = localScrollState.firstVisibleItemScrollOffset
}
}
LazyColumn(
state = localScrollState
) {
items(50) {
Text(modifier = Modifier
.padding(16.dp)
.fillMaxWidth(), text = "ITEM $it");
}
}
}
Upvotes: 4