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

Jetpack Compose中如何让Material3 Scaffold内容延伸至TopBar且不遮挡TabRow

问题解决:Material3 Scaffold内容延伸至TopBar且粘性TabRow不重叠

需求

让Material3 Scaffold的内容区域延伸至TopBar下方,但向下滚动时,内容中的粘性TabRow头部不能与TopBar重叠。当前设置LazyColumn顶部内边距为0.dp后,内容已延伸至TopBar,但滚动时TabRow停在屏幕顶部而非TopBar下方。

解决方案

核心思路是获取TopAppBar的实际高度,给粘性TabRow设置顶部偏移,使其滚动时停在TopBar下方:

  • 监听TopAppBar尺寸变化,记录真实高度,避免依赖固定值适配不同设备
  • 给粘性头部的ScrollableTabRow添加顶部内边距,值为TopAppBar的高度,确保滚动时无重叠
  • 保持TopAppBar与LazyColumn滚动行为联动,保证交互一致性

修改后的代码

@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun ProfileScreen() {
    var selectedTabIndex by remember { mutableIntStateOf(0) }
    val tabTitles = listOf("About", "Moments")
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
    // 记录TopAppBar的实际高度
    val topBarHeight = remember { mutableIntStateOf(0) }

    Scaffold(
        topBar = {
            TopAppBar(
                title = {},
                navigationIcon = {
                    IconButton(onClick = { }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "返回"
                        )
                    }
                },
                colors = topAppBarColors(
                    containerColor = Color.Transparent,
                    scrolledContainerColor = Color.Transparent
                ),
                scrollBehavior = scrollBehavior,
                // 监听尺寸变化保存TopAppBar高度
                modifier = Modifier.onSizeChanged {
                    topBarHeight.intValue = it.height
                }
            )
        },
        bottomBar = {
            Divider(modifier = Modifier.clip(RoundedCornerShape(20.dp)))
            Button(
                onClick = {}, modifier = Modifier
                    .fillMaxWidth()
                    .padding(20.dp)
            ) {
                Text("编辑资料")
            }
        }
    ) { paddingValue ->
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .background(onBackgroundDark)
                .padding(bottom = paddingValue.calculateBottomPadding()),
            state = rememberLazyListState(),
            contentPadding = PaddingValues(top = 0.dp)
        ) {
            item {
                HeaderBackground()
            }

            item {
                ProfileUserSection()
            }

            stickyHeader {
                ScrollableTabRow(
                    selectedTabIndex = selectedTabIndex,
                    modifier = Modifier
                        // 设置顶部内边距,让TabRow停在TopBar下方
                        .padding(top = topBarHeight.intValue.dp)
                        .padding(horizontal = 10.dp)
                        .fillMaxWidth()
                        .clip(RoundedCornerShape(20.dp, 20.dp, 0.dp, 0.dp)),
                    edgePadding = 0.dp,
                    divider = {}
                ) {
                    tabTitles.forEachIndexed { index, title ->
                        Tab(
                            selected = selectedTabIndex == index,
                            onClick = { selectedTabIndex = index },
                            text = { Text(title) }
                        )
                    }
                }
            }

            item {
                when (selectedTabIndex) {
                    0 -> TabAbout()
                    1 -> TabMoments()
                }
            }
        }
    }
}

效果说明

  • 初始状态:内容完整延伸至TopBar下方,TabRow随内容正常滚动
  • 滚动后:TabRow固定在TopBar下方,不会与TopBar产生重叠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:35:02