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

Android Jetpack Compose中如何隐藏/展开Scaffold的TopBar

实现自定义TopBar的滚动隐藏/展开效果

核心思路

借助Compose的滚动组件状态(比如LazyListState)监听滚动方向与偏移量,通过动画修改TopBar的垂直偏移,实现向下滚动隐藏、向上滚动展开的效果;若只需隐藏功能,可简化逻辑直接控制偏移量。

完整实现代码

@Composable
fun ScrollHideCustomTopBar() {
    // 定义自定义TopBar的高度
    val topBarHeight = 56.dp
    val topBarHeightPx = with(LocalDensity.current) { topBarHeight.toPx() }
    
    // 懒列表状态,用于监听滚动行为
    val lazyListState = rememberLazyListState()
    // 记录上一次滚动偏移,用来判断滚动方向
    val lastScrollOffset = remember { mutableStateOf(0) }
    // 控制TopBar显示/隐藏的偏移量
    val topBarOffset = remember { mutableStateOf(0f) }

    LaunchedEffect(lazyListState) {
        snapshotFlow { lazyListState.firstVisibleItemScrollOffset }
            .collect { currentOffset ->
                val scrollDiff = currentOffset - lastScrollOffset.value
                lastScrollOffset.value = currentOffset

                // 根据滚动方向更新TopBar偏移
                topBarOffset.value = when {
                    // 向下滚动:逐步隐藏TopBar,最大偏移为自身高度
                    scrollDiff > 0 -> min(topBarOffset.value + scrollDiff, topBarHeightPx)
                    // 向上滚动:逐步展开TopBar,偏移量回到0
                    scrollDiff < 0 -> max(topBarOffset.value + scrollDiff, 0f)
                    else -> topBarOffset.value
                }
            }
    }

    Scaffold(
        topBar = {
            // 自定义TopBar,通过offset控制显示位置
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(topBarHeight)
                    .offset(y = -topBarOffset.value.dp)
                    .background(Color.White)
                    .padding(horizontal = 16.dp, vertical = 12.dp),
                verticalArrangement = Arrangement.Center
            ) {
                Text(text = "自定义滚动隐藏TopBar", fontSize = 18.sp, fontWeight = FontWeight.Bold)
            }
        }
    ) { paddingValues ->
        LazyColumn(
            state = lazyListState,
            contentPadding = paddingValues,
            modifier = Modifier.fillMaxSize()
        ) {
            items(100) { index ->
                Text(
                    text = "列表项 $index",
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(16.dp),
                    fontSize = 16.sp
                )
            }
        }
    }
}

关键细节说明

  • 滚动监听:通过snapshotFlow订阅滚动组件的偏移量变化,对比前后值判断滚动方向。
  • 偏移控制:利用offset修饰符调整TopBar的垂直位置,向下滚动时让TopBar向上偏移至完全隐藏,向上滚动时逐步恢复原位。
  • 简化隐藏逻辑:若只需实现滚动隐藏(无需展开),可去掉方向判断,只要检测到向下滚动,直接将topBarOffset.value设为topBarHeightPx即可。
  • 适配其他滚动组件:如果使用的是Column配合verticalScroll,可替换为rememberScrollState,监听scrollState.value实现相同逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:15:46