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

CoordinatorLayout中ComposeView片段无法隐藏BottomNavigationView问题

问题原因

HideBottomViewOnScrollBehavior 依赖 View 体系的嵌套滚动(NestedScrolling)机制工作:当子 View 触发滚动时,会将滚动事件通知给父 CoordinatorLayout,Behavior 根据滚动方向控制底部导航栏的显示/隐藏。但默认情况下,ComposeView 不会将内部 LazyColumn 的滚动事件传递给 View 体系的嵌套滚动父容器,因此 Behavior 无法感知滚动,也就不会触发隐藏逻辑。而 NestedScrollView 本身是 View 体系组件,天然支持嵌套滚动,所以能正常触发效果。

解决方案

通过 Compose 的 nestedScroll Modifier,将 LazyColumn 的滚动事件桥接到 View 体系的嵌套滚动机制中,让 CoordinatorLayout 的 Behavior 能接收到滚动事件。

修改后的 Fragment 代码如下:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    return ComposeView(requireContext()).apply {
        // 开启ComposeView的嵌套滚动支持
        isNestedScrollingEnabled = true
        setContent {
            // 创建嵌套滚动连接,将Compose滚动事件传递给View体系
            val nestedScrollConnection = remember {
                object : NestedScrollConnection {
                    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                        val view = LocalView.current
                        if (view is NestedScrollingChild3) {
                            val consumed = IntArray(2)
                            // 通知父容器预滚动事件
                            view.dispatchNestedPreScroll(available.x.toInt(), available.y.toInt(), consumed, null, 0)
                            return Offset(consumed[0].toFloat(), consumed[1].toFloat())
                        }
                        return Offset.Zero
                    }

                    override fun onPostScroll(
                        consumed: Offset,
                        available: Offset,
                        source: NestedScrollSource
                    ): Offset {
                        val view = LocalView.current
                        if (view is NestedScrollingChild3) {
                            val consumedInt = intArrayOf(consumed.x.toInt(), consumed.y.toInt())
                            val availableInt = intArrayOf(available.x.toInt(), available.y.toInt())
                            // 通知父容器滚动完成事件
                            view.dispatchNestedScroll(consumedInt, availableInt, null, null, 0)
                        }
                        return Offset.Zero
                    }
                }
            }

            LazyColumn(
                modifier = Modifier
                    .fillMaxSize()
                    // 绑定嵌套滚动连接
                    .nestedScroll(nestedScrollConnection)
            ) {
                items(100) { index ->
                    Text(text = "Index is $index", color = Color.Black)
                }
            }
        }
    }
}
补充说明
  • isNestedScrollingEnabled = true:确保 ComposeView 本身作为 View 组件开启嵌套滚动支持,这样才能将事件传递给父 CoordinatorLayout。
  • NestedScrollConnection:在 Compose 滚动的预阶段(onPreScroll)和后阶段(onPostScroll),将滚动事件转换为 View 体系的嵌套滚动事件传递给父容器,让 HideBottomViewOnScrollBehavior 感知滚动方向和距离,从而执行显示/隐藏逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:15:34