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

Jetpack Compose 如何实现向下滚动隐藏底部导航栏、向上滚动展示效果

实现步骤

1. 调整BottomBar组件,新增显隐控制参数并添加过渡动画

修改你的BottomBar代码,接收显隐状态参数,添加滑动+淡入淡出的过渡效果:

@Composable
fun BottomBar(
    navController: NavController,
    isVisible: Boolean
) {
    val items = listOf(
        NavigationItem.Home,
        NavigationItem.Search
    )

    // 底部栏偏移量动画:隐藏时向下移出屏幕
    val bottomBarOffset by animateDpAsState(
        targetValue = if (isVisible) 0.dp else 56.dp, // 56.dp是Material Design标准底部导航栏高度
        animationSpec = tween(durationMillis = 300)
    )
    // 透明度动画:隐藏时逐步透明
    val alpha by animateFloatAsState(
        targetValue = if (isVisible) 1f else 0f,
        animationSpec = tween(durationMillis = 300)
    )

    BottomNavigation(
        backgroundColor = MaterialTheme.colors.DarkRed,
        contentColor = Color.White,
        modifier = Modifier
            .alpha(alpha)
            .offset(y = bottomBarOffset)
    ) {
        // 原有内部逻辑保持不变
        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentRoute = navBackStackEntry?.destination?.route

        items.forEach { item ->
            BottomNavigationItem(
                selected = currentRoute == item.route,
                icon = {
                    Icon(
                        imageVector = item.icon,
                        contentDescription = "Icon",
                        modifier = Modifier.size(28.dp)
                    )
                },
                alwaysShowLabel = false,
                selectedContentColor = Color.White,
                unselectedContentColor = Color.White.copy(0.4f),
                onClick = {
                    navController.navigate(item.route){
                        navController.graph.startDestinationRoute?.let{route ->
                            popUpTo(route){
                                saveState = true
                            }
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )
        }
    }
}

2. 在MainScreen中添加滚动监听逻辑,控制底部栏显隐

通过NestedScrollConnection监听全局滚动事件,根据滚动方向更新显隐状态:

@Composable
fun MainScreen(){
    val navController = rememberNavController()
    // 底部栏显隐状态
    var isBottomBarVisible by remember { mutableStateOf(true) }

    // 嵌套滚动监听器,捕捉滚动方向
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                // 垂直滚动偏移量:大于0是向上滚动,小于0是向下滚动
                val delta = available.y
                if (delta > 0 && !isBottomBarVisible) {
                    // 向上滚动、底部栏隐藏时,显示底部栏
                    isBottomBarVisible = true
                } else if (delta < 0 && isBottomBarVisible) {
                    // 向下滚动、底部栏显示时,隐藏底部栏
                    isBottomBarVisible = false
                }
                // 返回0表示不消费滚动事件,事件继续传递给子组件
                return Offset.Zero
            }
        }
    }

    Scaffold(
        topBar = { ActionBar("Books") },
        bottomBar = { BottomBar(navController = navController, isVisible = isBottomBarVisible) }
    ){ paddingValues ->
        NavigationGraph(
            navController = navController,
            modifier = Modifier
                .padding(paddingValues)
                // 绑定滚动监听器
                .nestedScroll(nestedScrollConnection)
        )
    }
}

3. 可选适配:特殊页面强制显示底部栏

如果部分页面没有滚动布局(比如空白页、固定内容页),可以根据路由判断强制显示底部栏:
在MainScreen中获取当前路由,修改isBottomBarVisible的更新逻辑即可:

val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
// 示例:搜索页不需要滚动隐藏,强制显示底部栏
val forceShowBottomBar = currentRoute == NavigationItem.Search.route

// 滚动判断里加上强制显示的逻辑
if (delta > 0 && !isBottomBarVisible || forceShowBottomBar) {
    isBottomBarVisible = true
} else if (delta < 0 && isBottomBarVisible && !forceShowBottomBar) {
    isBottomBarVisible = false
}

注意事项

  • 如果你的页面用LazyColumn实现列表,不需要额外配置,默认支持嵌套滚动
  • 如果用普通Column,需要添加.verticalScroll(rememberScrollState())修饰符开启滚动能力
  • 可以根据需要调整动画时长、底部栏高度参数适配你的设计需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:51:00