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
相关产品推荐
相关产品推荐

