Jetpack Compose:LazyRow 滚动百分比?

问题描述 投票:0回答:1

我正在尝试在 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))
        }
    }
}

选择第二个项目后的外观:

enter image description here

android kotlin user-interface android-jetpack-compose lazycolumn
1个回答
0
投票

我相信您正在尝试创建类似寻呼机的功能。为此,您可以使用 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 的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.