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

Jetpack Compose:嵌套LazyRow在LazyColumn滚动时无法滑动求助

Jetpack Compose嵌套滚动问题:LazyRow无法横向滑动

问题描述

将LazyRow嵌套在Column内后,下方LazyColumn的垂直滚动功能正常,但LazyRow无法触发横向滑动。

重现代码

@Composable
fun Screen() {
    ReusableScaffold(
        scaffoldTitle = "Demo",
        scaffoldContent = {
            MyScreenContent(contentPadding = it)
        }
    )
}

@Composable
fun MyReusableScaffold(scaffoldTitle: String, scaffoldFab: @Composable () -> Unit = {},
                       scaffoldContent: @Composable (contentPadding: PaddingValues) -> Unit) {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            LargeTopAppBar(
                title = {Text(text = scaffoldTitle)},
                scrollBehavior = scrollBehavior
            )
        },
        content = { contentPadding -> scaffoldContent(contentPadding = contentPadding) }
    )
}

@Composable
fun MyScreenContent(
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = PaddingValues()
) {
    // 示例数据集
    val rowItems = arrayOf(
        RowItems.ItemRowCheetah,
        RowItems.ItemRowPuma,
        RowItems.ItemRowJaguar,
        RowItems.ItemRowPanther,
        RowItems.ItemRowTiger
    )

    val columnItems = arrayOf(
        ColumnItems.ItemPetitFour,
        ColumnItems.ItemCupcake,
        ColumnItems.ItemDonut,
        ColumnItems.ItemEclair,
        ColumnItems.ItemFroyo
    )

    Box(modifier = modifier
        .fillMaxSize()
        .padding(contentPadding)) {
        Column(content = {
                ReusableLazyRow(
                    lazyRowItems = rowItems,
                    lazyRowItemLayout = {
                        Card(
                            modifier = Modifier
                                .height(250.dp)
                                .padding(16.dp),
                            shape = RoundedCornerShape(size = 16.dp),
                        ) {
                            Column {
                                Text(text = it.rowItemTitle)
                                Text(text = it.rowItemDesc)
                            }
                        }
                    }
                )

                ReusableLazyColumn(
                    lazyColumnItems = columnItems,
                    lazyColumnItemLayout = {
                        Row { Text(text = it.columnItemTitle) }
                    }
                )
            }
        )
    }
}

@Composable
fun <T> ReusableLazyRow(lazyRowItems: Array<T>,
                        lazyRowItemLayout: @Composable Any.(item: T) -> Unit,
                        onClickLazyRowItem: (T) -> Unit
) {
    val listState = rememberLazyListState()

    LazyRow(
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp),
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 0.dp)
    ) {
        items(lazyRowItems) { itemR ->
            Column(modifier = Modifier
                .clickable {
                    onClickLazyRowItem(itemR)
                }) {
                lazyRowItemLayout(itemR)
            }
        }
    }
}

@Composable
fun <T> ReusableLazyColumn(
    lazyColumnItems: Array<T>,
    lazyColumnItemLayout: @Composable Any.(item: T) -> Unit,
    onClickLazyColumnItem: (T) -> Unit = {}
) {
    val listState = rememberLazyListState()

    LazyColumn(
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 20.dp)
    ) {
        items(lazyColumnItems) { itemC -> 
            Row(modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    onClickLazyColumnItem(itemC)
                }) {
                lazyColumnItemLayout(itemC)
            }
        }
    }
}

界面截图

界面截图1
界面截图2

问题原因

  1. 父级Scaffold的nestedScrollConnection会拦截垂直方向触摸事件,当用户在LazyRow上尝试横向滑动时,事件可能被错误识别为垂直滚动意图,导致LazyRow无法获取到横向滚动的触摸信号。
  2. ReusableLazyRow的onClickLazyRowItem参数未设置默认值,调用时未传参会引发编译错误。

解决方案

1. 添加嵌套滚动连接处理冲突

给LazyRow添加nestedScroll修饰符,通过rememberNestedScrollInteropConnection()处理跨方向滚动事件的优先级,确保LazyRow能正确响应横向滑动:

@Composable
fun <T> ReusableLazyRow(lazyRowItems: Array<T>,
                        lazyRowItemLayout: @Composable Any.(item: T) -> Unit,
                        onClickLazyRowItem: (T) -> Unit = {} // 添加默认值解决编译问题
) {
    val listState = rememberLazyListState()
    val nestedScrollConnection = rememberNestedScrollInteropConnection()

    LazyRow(
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp)
            .nestedScroll(nestedScrollConnection), // 处理嵌套滚动冲突
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 0.dp)
    ) {
        items(lazyRowItems) { itemR ->
            Column(modifier = Modifier
                .clickable {
                    onClickLazyRowItem(itemR)
                }) {
                lazyRowItemLayout(itemR)
            }
        }
    }
}

2. 修复可选参数默认值

给MyReusableScaffold的scaffoldFab参数添加默认空实现,避免调用时未传参的编译错误:

@Composable
fun MyReusableScaffold(scaffoldTitle: String, scaffoldFab: @Composable () -> Unit = {},
                       scaffoldContent: @Composable (contentPadding: PaddingValues) -> Unit) {
    // 原有代码不变
}

验证效果

修改后,LazyRow可正常横向滑动,LazyColumn的垂直滚动功能不受影响,两种滚动行为可独立触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:43:14