Gam*_*015 7 android android-architecture-navigation android-jetpack-navigation android-jetpack-compose android-jetpack-compose-material3
当在两个屏幕之间导航时,每个屏幕都有一个带有 TopAppBar 的脚手架,TopAppBar 会以动画方式退出 UI 并返回。(在我的示例中短暂的白色闪烁,就像按钮动画一样)
我想这种行为是预期的,因为 compose 无法知道,这两者应该被视为相同。
有没有什么方法可以防止这种行为,而不将标题状态提升到 MainNavigation 可组合项,以便仅在导航上重绘标题?我认为在 flutter 中几乎所有小部件都有一个名为“key”的属性,jetpack compose 中也有类似的属性吗?
对于这个小例子来说,这很好,但是当有一个更复杂的导航图时,我担心 MainNavigation 会因属于其他地方的语义而过载,例如加载数据以显示项目名称......
代码
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
UnwelcomeNavAnimationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainNavigation()
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "screen1") {
composable("screen1") {
Scaffold(
topBar = {
TopAppBar(title = {
Text(
text = "Screen 1",
color = MaterialTheme.colorScheme.onPrimary
)
}, colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary
))
}
) {
Button(
onClick = {
navController.navigate("screen2")
},
modifier = Modifier.padding(it)
) {
Text(text = "Switch")
}
}
}
composable("screen2") {
Scaffold(
topBar = {
TopAppBar(title = {
Text(
text = "Screen 2",
color = MaterialTheme.colorScheme.onPrimary
)
}, colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary
))
}
) {
Button(
onClick = {
navController.navigate("screen1")
},
modifier = Modifier.padding(it)
) {
Text(text = "Switch")
}
}
}
// TODO: Add more destinations
}
}
Run Code Online (Sandbox Code Playgroud)
依赖关系
implementation 'androidx.navigation:navigation-compose:2.5.3'
Run Code Online (Sandbox Code Playgroud)
您需要从 NavHost 中删除应用程序栏,因此您将使用单个脚手架。为了正确显示它们,您需要首先检查当前路线,然后根据它显示应用栏。
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
Scaffold(
topBar = {
when (currentRoute) {
"screen1" -> {
TopAppBar(title = {
Text(
text = "Screen 1",
color = MaterialTheme.colorScheme.onPrimary
)
}, colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary
))
}
"screen2" -> {
TopAppBar(title = {
Text(
text = "Screen 2",
color = MaterialTheme.colorScheme.onPrimary
)
}, colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary
))
}
else -> {
// mandatory blank app bar to show when the start destination hasn't been yet navigated
TopAppBar(title = {
Text(
text = "",
color = MaterialTheme.colorScheme.onPrimary
)
}, colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary
))
}
}
}
) {
NavHost(
navController = navController,
startDestination = "screen1",
modifier = Modifier.padding(it)
) {
composable("screen1") {
Button(
onClick = {
navController.navigate("screen2")
},
modifier = Modifier.padding(it)
) {
Text(text = "Switch")
}
}
composable("screen2") {
Button(
onClick = {
navController.navigate("screen1")
},
modifier = Modifier.padding(it)
) {
Text(text = "Switch")
}
}
// TODO: Add more destinations
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |