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

Android基于Voyager导航实现不同TopAppBar+统一BottomAppBar

在Android应用中使用Voyager实现差异化TopAppBar与全局统一BottomAppBar

需求说明

  • 不同页面展示对应自定义的TopAppBar(示例:首页标题为“home”,设置页标题为“settings”)
  • 全局保持BottomAppBar样式一致

基础实现代码

主布局MainCompose

@Composable
fun MainCompose(){
    AppTheme {
        Navigator(ProjectScreen()) {navigation ->
            Scaffold(
                bottomBar = {
                    BottomNavigationBar()
                },
            ){innerPadding ->
                SlideTransition(
                    navigator = navigation,
                    modifier = Modifier.padding(innerPadding)
                )
            }
        }
    }
}

全局BottomAppBar实现

@Composable
fun BottomNavigationBar() {

    val navigator = LocalNavigator.currentOrThrow

    BottomAppBar(
        actions = {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceEvenly
            ) {
                allScreens.forEach { navLinks ->
                    TextButton(onClick = {
                        navigator.push(navLinks.screen)
                    }) {
                        Column(
                            horizontalAlignment = Alignment.CenterHorizontally
                        ) {
                            Row {
                                navLinks.icon()
                            }
                            Spacer(Modifier.padding(4.dp))
                            Row {
                                Text(navLinks.name, style = MaterialTheme.typography.labelMedium)
                            }
                        }
                    }
                }
            }
        }
    )
}

可行解决方案实现

修改后的主布局MainCompose

通过监听导航栈当前活跃页面,动态渲染对应TopAppBar:

@Composable
fun MainCompose(){
   AppTheme {
    Navigator(ProjectScreen()) {navigation ->
        val currentScreen = navigation.lastItem

        Scaffold(
            bottomBar = {
                BottomNavigationBar()
            },
            topBar = {
                TopBarForCurrentScreen(currentScreen ,navigation)
            }
        ){innerPadding ->
            SlideTransition(
                navigator = navigation,
                modifier = Modifier.padding(innerPadding)
            )
          }
      }
   }
}

页面差异化TopAppBar实现

根据当前页面类型,返回对应定制化的TopAppBar:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopBarForCurrentScreen(currentScreen: Screen ,navigation: Navigator) {
when (currentScreen) {
    is ProjectScreen -> {
        TopAppBar(
            navigationIcon = {
                Icon(
                    painter = painterResource(R.drawable.project), contentDescription = "icon",
                    Modifier.size(20.dp)
                )
            },
            title = {
                Text(
                    "Projects",
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
            },
            colors = TopAppBarDefaults.topAppBarColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                titleContentColor = MaterialTheme.colorScheme.onSecondaryContainer
            ),
            actions = {
                IconButton(onClick = {}) {
                    Icon(Icons.Filled.Search, contentDescription = "search")
                }
                Button (
                    onClick = {
                        navigation.push(FormScreen())
                    },
                    colors = ButtonDefaults.buttonColors(
                        containerColor = MaterialTheme.colorScheme.tertiaryContainer,
                        contentColor = MaterialTheme.colorScheme.onTertiaryContainer
                    )
                ) {
                    Row(
                        horizontalArrangement = Arrangement.Center,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Column {
                            Icon(
                                Icons.Filled.Add,
                                contentDescription = "Create"
                            )
                        }
                        Column {
                            Text("Create")
                        }
                    }
                }
            }
        )
    }

    is FormScreen -> {
        TopAppBar(
            navigationIcon = {
                Icon(
                    painter = painterResource(R.drawable.form), contentDescription = "icon",
                    Modifier.size(20.dp)
                )
            },
            title = {
                Text(
                    "Forms",
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
            },
            colors = TopAppBarDefaults.topAppBarColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                titleContentColor = MaterialTheme.colorScheme.onSecondaryContainer
            ),
        )
    }

    else -> {
        TopAppBar(
            navigationIcon = {
                Icon(
                    painter = painterResource(R.drawable.project), contentDescription = "icon",
                    Modifier.size(20.dp)
                )
            },
            title = {
                Text(
                    "Projects",
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
            },
            colors = TopAppBarDefaults.topAppBarColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer,
                titleContentColor = MaterialTheme.colorScheme.onSecondaryContainer
            ),
            actions = {
                IconButton(onClick = {}) {
                    Icon(Icons.Filled.Search, contentDescription = "search")
                }
            }
        )
    }
}
}

方案说明

  • 借助Voyager的navigation.lastItem获取当前活跃页面,实现TopAppBar的动态切换
  • BottomAppBar直接在Scaffold中全局配置,确保所有页面样式统一
  • 通过when分支对不同页面类型做差异化TopAppBar定制,后续新增页面只需扩展分支即可

内容的提问来源于stack exchange,提问作者W.A Rajinda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:33:19