Zoltan Demant
06/16/2025, 9:54 AMHorizontalPager
will get stuck in between two pages when I programmatically scroll between them.
(code & details in 🧵_)_Zoltan Demant
06/16/2025, 9:59 AMmutableStateOf<Int>
that decides which page the pager should start at, or scroll to. This gets updated both programatically, and in reaction to user scroll events.
In the scenario where the pager got stuck, these are the events that lead up to it:
• Pages are [A, B, C]
• User is at page B (at index 1)
• The backing list to the pager is reordered -> [B, A, C]
• User is at page B (now at index 0)
• The pager is set to programatically scroll to A
And the pager is now stuck between B & A.
(this is extremely rare, but very confusing when it does happen).Zoltan Demant
06/16/2025, 9:59 AM@Composable
fun rememberPagerState(
page: Int,
pageCount: () -> Int,
onPageSelected: (Int) -> Unit,
): PagerState {
val state =
rememberPagerState(
initialPage = page,
pageCount = pageCount,
)
val currentPage by rememberUpdatedState(page)
val currentOnPageSelected by rememberUpdatedState(onPageSelected)
LaunchedEffect(state) {
snapshotFlow(state::targetPage).distinctUntilChanged().collect { newPage ->
if (newPage != currentPage) {
delay(50.milliseconds)
if (newPage == state.targetPage) {
currentOnPageSelected(newPage)
}
}
}
}
LaunchedEffect(currentPage) {
if (state.settledPage != currentPage && !state.isScrollInProgress) {
state.animateScrollToPage(currentPage)
}
}
return state
}
Zoltan Demant
06/16/2025, 10:40 AMPagerState.targetPage
to instead use PagerState.currentPage
(updated when the pager has settled on the page, instead of mid-scroll) this bug will be fixed.
But, I need the fast updates so that I can update elements outside of the pager to match the page the user is at faster (currentPage takes roughly 0.5s longer and its very noticeable).Zach Klippenstein (he/him) [MOD]
06/16/2025, 3:08 PMTolriq
06/16/2025, 6:11 PM