我正在尝试在 LazyRow 上实现滚动指示器。理想情况下,它会在滚动时平滑过渡,但我读到这是不可能的,因为我们只能从状态访问
firstVisibleItemIndex
。但即便如此,我仍然无法按照我想要的方式实现它,因为我的项目只占据屏幕宽度的 90%,因此会显示之前项目的一点点。当选择第二个项目时,第一个项目在屏幕上仍然可见,因此 firstVisibleItemIndex
永远不会真正改变,直到您滚动到它上面一点。
有没有办法顺利获取可滚动百分比?如果没有,我该如何解决我的情况,考虑到不占用父级总宽度的项目:
这就是我到目前为止所拥有的。代码适合隐藏敏感信息,但这应该运行:
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun SnappingRowWithIndicator(items: List<Int>) {
val state = rememberLazyListState()
val firstVisibleItemIndex = state.firstVisibleItemIndex
val percent = (firstVisibleItemIndex / (items.size).toFloat()) * 100f
LaunchedEffect(percent) {
val scrollText = "scroll: $percent"
println(scrollText)
}
LazyRow(
horizontalArrangement = Arrangement.spacedBy(16.dp),
state = state,
flingBehavior = rememberSnapFlingBehavior(lazyListState = state)
) {
items(items) { dto ->
Text(
modifier = Modifier
.height(32.dp)
.fillParentMaxWidth(0.9f)
.background(Color.White)
.padding(vertical = 8.dp),
color = Color.Black,
text = dto.toString(),
textAlign = TextAlign.Center
)
}
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.CenterHorizontally)
) {
items.forEachIndexed { index, _ ->
// todo color and not color the dots according to the index and the percentage scrolled
Box(modifier = Modifier
.size(8.dp)
.background(color = DesignSystem.Color.white, shape = CircleShape))
}
}
}
选择第二个项目后的外观:
我相信您正在尝试创建类似寻呼机的功能。为此,您可以使用 HorizontalPager。
这是更新后的代码。
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun SnappingRowWithIndicator(items: List<Int>) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
val pagerState = rememberPagerState(pageCount = {
items.size
})
HorizontalPager(
state = pagerState,
contentPadding = PaddingValues(horizontal = 16.dp),
pageSpacing = 8.dp,
pageSize = PageSize.Fixed(LocalConfiguration.current.screenWidthDp.dp - 32.dp)
) { page ->
Text(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
.padding(vertical = 8.dp),
color = Color.Black,
text = "Page: $page",
textAlign = TextAlign.Center
)
}
Row(
Modifier
.wrapContentHeight()
.fillMaxWidth()
.align(Alignment.CenterHorizontally),
horizontalArrangement = Arrangement.Center
) {
repeat(pagerState.pageCount) { iteration ->
val color = if (pagerState.currentPage == iteration) Color.White else Color.Gray
Box(
modifier = Modifier
.padding(2.dp)
.clip(CircleShape)
.background(color)
.size(8.dp)
)
}
}
}
}
您可以在此处阅读有关 Compose 中的 Pager 的更多信息。