我有一个使用水平寻呼机的Jetpack Compose应用程序。我看到的行为是,当我滑动到下一页时,它平滑地移动,但当我滑动回屏幕时,屏幕向前移动了大约3/4,然后暂停,然后如果我等待它完成滑动。
问题:
这是正常的吗?
或者它可能是我的实现?
其他人有过这样的经历吗?
这取决于水平页的内容。当我使用简单的线圈图像时,它工作得很好。但是当我在水平分页中有垂直分页/延迟列时,它就会滞后。这里还提到:如何优化滞后的JetPack Compose布局
有一个技巧可以解决这个问题:
你必须使用beyondBoundsPageCount参数设置为1,加载相邻的两个页面内容,并且观察已解决的页面只有当你停止滚动时才开始加载即将到来的内容(这意味着:当前页面已解决)。
默认的分页行为是在滚动开始时开始加载相邻页面的内容-即使是1px-这使得您的滚动由于进入阻塞主线程的组合而变得混乱。
我已经对这个问题做了更多的解释
val pagerState = rememberPagerState(initialPage = initialPage,) {
cycles.size
}
val beyondBoundsPageCount = 1
HorizontalPager(
modifier = modifier.size(animatedSize),
state = pagerState,
beyondBoundsPageCount = beyondBoundsPageCount,
key = { cycles[it].id },
) { page ->
val cycle = cycles[page]
val isCurrentPageSettled = settledPage == page
// rememberUpdatedState is only used as a value Holder because of closure in produceState producer parameter
val currentIsScrollInProgress by rememberUpdatedState(newValue = isScrollInProgress)
val abs by rememberUpdatedHolder(newValue = abs(settledPage - page))
val showProgress by produceState(initialValue = true) {
while (currentIsScrollInProgress) delay(50)
if (abs > 0) { // <=> if (settledPage != page)
delay(500) // to render adjacent pages after the middle/current one, I’ve chosen 500 but it could be less
while (currentIsScrollInProgress) delay(50)
}
value = false
}
if ((abs > beyondBoundsPageCount) || showProgress) {
Box(
modifier = Modifier
.size(dynamicSize)
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator()
}
} else {
// In order to not update adjacent pages
@Suppress("NAME_SHADOWING")
val cycle by remember { mutableStateOf(cycle) }.also {
if (page == targetPage) it.value = cycle // or if(isCurrentPageSettled) or if (page == currentPage) that’s depends on when you want to allow the adjacent pages to start updating
}
CycleScreen(
cycle = cycle,
...
)
}
}