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

Jetpack Compose TopAppBar:如何按页面保存折叠状态

解决方案

当然可行,核心是给每个页面独立维护TopAppBarState和对应的滚动行为,而非在共享的父组件中复用同一个状态。

你的当前代码里,scrollBehavior是在Content组件中创建的,所有底部导航页面都会共用这个状态,导致切换页面时保留之前的折叠状态。只需把滚动状态的创建逻辑移到每个单独的页面组件内部即可:

修改后的示例代码

// 父级Content组件,负责底部导航和Scaffold框架
@Composable
fun Content() {
    val navController = rememberNavController()
    val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route

    Scaffold(
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    selected = currentRoute == "page1",
                    onClick = { navController.navigate("page1") },
                    icon = { Icon(Icons.Default.Home, contentDescription = "页面1") }
                )
                NavigationBarItem(
                    selected = currentRoute == "page2",
                    onClick = { navController.navigate("page2") },
                    icon = { Icon(Icons.Default.Settings, contentDescription = "页面2") }
                )
            }
        }
    ) { innerPadding ->
        NavHost(navController = navController, startDestination = "page1") {
            composable("page1") {
                Page1(innerPadding = innerPadding)
            }
            composable("page2") {
                Page2(innerPadding = innerPadding)
            }
        }
    }
}

// 页面1组件,独立维护自己的TopAppBar状态
@Composable
fun Page1(innerPadding: PaddingValues) {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection)
            .padding(innerPadding)
    ) {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            colors = topAppBarColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                titleContentColor = MaterialTheme.colorScheme.primary,
            ),
            title = { Text("页面1") }
        )
        // 页面1的滚动内容
        LazyColumn {
            items(100) {
                Text("条目 $it", modifier = Modifier.padding(16.dp))
            }
        }
    }
}

// 页面2组件,同样独立维护状态
@Composable
fun Page2(innerPadding: PaddingValues) {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection)
            .padding(innerPadding)
    ) {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            colors = topAppBarColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                titleContentColor = MaterialTheme.colorScheme.primary,
            ),
            title = { Text("页面2") }
        )
        // 页面2的滚动内容
        LazyColumn {
            items(50) {
                Text("页面2 条目 $it", modifier = Modifier.padding(16.dp))
            }
        }
    }
}

关键说明

  • 每个页面组件(如Page1、Page2)内部单独创建scrollBehavior和TopAppBarState,确保状态完全隔离。
  • 将Modifier.nestedScroll应用到每个页面的根布局上,而非父级Scaffold,这样滚动事件只会影响当前页面的TopAppBar。
  • 切换页面时,新页面的TopAppBarState是全新初始化的,默认处于展开状态,只有当前页面滚动时才会触发折叠逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:10:10