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) } } } }
界面截图


问题原因
- 父级Scaffold的
nestedScrollConnection会拦截垂直方向触摸事件,当用户在LazyRow上尝试横向滑动时,事件可能被错误识别为垂直滚动意图,导致LazyRow无法获取到横向滚动的触摸信号。 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
相关产品推荐
相关产品推荐

