有没有办法在 Jetpack Compose 中创建滚轮?

Dzi*_*buz 6 android-jetpack android-jetpack-compose android-jetpack-compose-list

有没有办法创建看起来像 iOS 上的滚轮日期选择器的循环滚轮?

到处寻找答案但没有找到。

在此输入图像描述

z.g*_*g.y 0

抱歉,但是很难找到这个用例的示例,因此我会在这里为任何寻找类似内容的人留下一个粗略的工作示例。我成功地基于这篇文章Circular Endless Scrolling创建了一个无限的滚动,并应用了一点逻辑来实现小时垂直滚动

这可以显示 24 小时格式和 12 小时格式,尽管整体还不完整,尤其是 24 小时格式

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun CircularClock(
    hourSize : Int,
    initialHour: Int
) {
    val height = 90.dp
    val cellSize = height / 3
    val cellTextSize = LocalDensity.current.run { (cellSize / 2f).toSp() }

    // just prepare an offset of 1 hour when format is set to 12hr format
    val hourOffset = if (hourSize == 12) 1 else 0
    val expandedSize = hourSize * 10_000_000
    val initialListPoint = expandedSize / 2
    val targetIndex = initialListPoint + initialHour - 1

    val scrollState = rememberLazyListState(targetIndex)
    val hour by remember { derivedStateOf { (scrollState.firstVisibleItemIndex + 1) % hourSize }}

    if (!scrollState.isScrollInProgress) {
        Log.e("FocusedHour", "${hour + hourOffset}")
    }

    LaunchedEffect(Unit) {
        // subtract the offset upon initial scrolling, otherwise it will look like
        // it moved 1 hour past the initial hour when format is set to 12hr format
        scrollState.scrollToItem(targetIndex - hourOffset)
    }

    Box(
        modifier = Modifier
            .height(height)
            .wrapContentWidth()
    ) {
        LazyColumn(
            modifier = Modifier
                .wrapContentWidth(),
            state = scrollState,
            flingBehavior = rememberSnapFlingBehavior(lazyListState = scrollState)
        ) {
            items(expandedSize, itemContent = {

                // if 12hr format, move 1 hour so instead of displaying 00 -> 11
                // it will display 01 to 12
                val num = (it % hourSize) + hourOffset
                Box(
                    modifier = Modifier
                        .size(cellSize),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = String.format("%02d", num),
                        style = MaterialTheme.typography.overline.copy(
                        color = Color.Gray,
                        fontSize = cellTextSize
                    )
                )
            }
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

免责声明:这个实现在一定高度上还不能很好地工作,因为我依赖于scrollstate可见的项目,任何更正将不胜感激。

对于捕捉效果:我使用了Chrisbane snapper