You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何实现两个横向列表按不同速度同步滚动?

实现方案

你原来的实现思路存在问题:同一个rememberScrollState会让两个滚动组件完全绑定偏移量,自然无法实现不同滚动速度。你需要拆分出两个独立的滚动状态,通过状态监听按比例联动即可:

完整实现代码

import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import kotlin.math.roundToInt

// 可根据需求调整滚动倍率,这里顶部速度是底部的2倍
private const val SCROLL_RATIO = 2f

@Composable
fun SpeedDiffScrollRow() {
    val topScrollState = rememberScrollState()
    val bottomScrollState = rememberScrollState()
    // 防止双向监听触发滚动死循环
    var isProgrammaticScroll by remember { mutableStateOf(false) }

    // 监听顶部滚动,按比例驱动底部滚动
    LaunchedEffect(topScrollState.value) {
        if (!isProgrammaticScroll) {
            isProgrammaticScroll = true
            val targetBottomOffset = (topScrollState.value / SCROLL_RATIO)
                .roundToInt()
                .coerceIn(0, bottomScrollState.maxValue)
            bottomScrollState.scrollTo(targetBottomOffset)
            isProgrammaticScroll = false
        }
    }

    // 监听底部滚动,按比例驱动顶部滚动(如果不需要支持滑动底部控制,可删除这段)
    LaunchedEffect(bottomScrollState.value) {
        if (!isProgrammaticScroll) {
            isProgrammaticScroll = true
            val targetTopOffset = (bottomScrollState.value * SCROLL_RATIO)
                .roundToInt()
                .coerceIn(0, topScrollState.maxValue)
            topScrollState.scrollTo(targetTopOffset)
            isProgrammaticScroll = false
        }
    }

    Row(modifier = Modifier.horizontalScroll(topScrollState)) {
        Images()
    }
    // 如果不需要支持滑动底部控制,可给horizontalScroll加enabled = false参数
    Row(modifier = Modifier.horizontalScroll(bottomScrollState)) {
        Legend()
    }
}

可选优化

  • 如果需要滚动带惯性动画效果,可以把scrollTo替换为animateScrollTo,注意调整动画时长避免跟手延迟
  • 如果只允许用户操作顶部滚动区域,可删除底部滚动的监听逻辑,同时给底部horizontalScroll添加enabled = false参数,减少不必要的状态监听

内容的提问来源于stack exchange,提问作者axebau24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:45:05