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

Jetpack Compose:嵌套LazyRow的LazyColumn点击切换附件方案

解决信息流中图片视频混合展示的三个核心问题

1. 解决ExoPlayer拦截点击事件的问题

ExoPlayer的PlayerView会默认消费触摸事件,导致父布局或其他Composable的点击回调无法触发。可以通过给PlayerView添加触摸事件监听,拦截点击事件并转发到自定义回调:

AndroidView(
    factory = { context ->
        PlayerView(context).apply {
            player = exoPlayer
            // 用GestureDetector区分点击和滑动事件
            val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
                override fun onSingleTapUp(e: MotionEvent): Boolean {
                    // 触发自定义点击回调
                    onAttachmentClick()
                    return true // 拦截事件,不让ExoPlayer处理点击
                }

                // 保留ExoPlayer的滑动快进功能(不需要可移除)
                override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
                    return super.onScroll(e1, e2, distanceX, distanceY)
                }
            })

            setOnTouchListener { _, event ->
                gestureDetector.onTouchEvent(event)
                // 非点击事件交给ExoPlayer处理
                return@setOnTouchListener false
            }
        }
    },
    modifier = Modifier.fillMaxSize()
)

2. 实现LazyRow自动滚动到当前附件索引

使用LazyListState配合LaunchedEffect监听索引变化,自动滚动到目标位置,同时用animateScrollToItem实现幻灯片流畅切换效果:

// 初始化LazyListState
val lazyListState = rememberLazyListState()
val currentIndex by feedViewModel.currentAttachmentIndex.collectAsState()

// 监听索引变化,自动触发滚动
LaunchedEffect(currentIndex) {
    lazyListState.animateScrollToItem(currentIndex)
}

LazyRow(
    state = lazyListState,
    userScrollEnabled = false, // 提前禁用手动滑动
    modifier = Modifier.fillMaxSize()
) {
    items(feedViewModel.currentPost.attachments.size) { index ->
        AttachmentItem(
            attachment = feedViewModel.currentPost.attachments[index],
            onAttachmentClick = {
                feedViewModel.nextAttachment() // 更新当前索引
            }
        )
    }
}

注意:确保currentAttachmentIndex是Flow/StateFlow类型,通过collectAsState()实时监听变化。

3. 禁用LazyRow的手动滑动功能

直接给LazyRow设置userScrollEnabled = false参数即可阻止用户手动滚动:

LazyRow(
    state = lazyListState,
    userScrollEnabled = false, // 禁用手动滑动
    modifier = Modifier.fillMaxSize()
) {
    // 列表项内容
}

如果旧版Compose中该参数不生效,可通过pointerInput拦截所有触摸事件:

LazyRow(
    state = lazyListState,
    modifier = Modifier
        .fillMaxSize()
        .pointerInput(Unit) {
            awaitPointerEventScope {
                while (true) {
                    val event = awaitPointerEvent()
                    event.changes.forEach { it.consume() }
                }
            }
        }
) {
    // 列表项内容
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:42:34