在Jetpack Compose中以不同的速度滚动多个列表多个、中以、速度、不同

2023-09-03 10:00:16 作者:别害怕我在i

目前我正在尝试开发一种特殊的图像旋转木马,它基本上有两行(一行在顶部放置图像,另一行在底部(宽度较短),使用名称作为参考)

问题是,我需要用Jetpack Compose(只需一些滚动监听程序在常规Android中即可完成)来实现滚动顶部行的速度快于底部行的速度。

Jetpack Compose环境搭建

我能够实现同时滚动各行,但它们以相同的速度滚动。我需要以两倍的速度滚动第一个,才能达到我想要的效果。 以下是我尝试的代码。

val scrollState = rememberScrollState()
Row(modifier = Modifier.horizontalScroll(scrollState)) {
   Images()
}
Row(modifier = Modifier.horizontalScroll(scrollState)) {
   Legend()
}

推荐答案

如果只需要一个Row即可滚动,则可以每次创建新的ScrollState

val scrollState = rememberScrollState()
Row(modifier = Modifier.horizontalScroll(scrollState)) {
    repeat(100) {
        Text(it.toString())
    }
}
Row(
    modifier = Modifier.horizontalScroll(
        ScrollState(scrollState.value * 2),
        enabled = false
    )
) {
    repeat(200) {
        Text(it.toString())
    }
}

请注意,就性能而言,此解决方案可能不是最好的,因为它为滚动的每个像素创建了一个类。

另一种解决方案是将它们与LaunchedEffect同步。它还允许您双向滚动同步。

@Composable
fun TestScreen(
) {
    val scrollState1 = rememberScrollState()
    Row(
        horizontalArrangement = Arrangement.spacedBy(10.dp),
        modifier = Modifier.horizontalScroll(scrollState1)
    ) {
        repeat(100) {
            Text(it.toString())
        }
    }
    val scrollState2 = rememberScrollState()
    Row(
        horizontalArrangement = Arrangement.spacedBy(10.dp),
        modifier = Modifier.horizontalScroll(scrollState2)
    ) {
        repeat(200) {
            Text(it.toString())
        }
    }
    SyncScrollTwoWay(scrollState1, scrollState2, 2f)
}

@Composable
fun SyncScrollTwoWay(scrollState1: ScrollState, scrollState2: ScrollState, multiplier: Float) {
    SyncScroll(scrollState1, scrollState2, multiplier)
    SyncScroll(scrollState2, scrollState1, 1 / multiplier)
}

@Composable
fun SyncScroll(scrollState1: ScrollState, scrollState2: ScrollState, multiplier: Float) {
    if (scrollState1.isScrollInProgress) {
        LaunchedEffect(scrollState1.value) {
            scrollState2.scrollTo((scrollState1.value * multiplier).roundToInt())
        }
    }
}

但它也有一个缺点:滚动几乎不会有延迟,因此第二个滚动视图将始终比滚动的滚动视图落后一帧。