我有两个屏幕,它们都有自己的Scaffold
和TopAppBar
。当我使用Jetpack Navigation Compose库在它们之间导航时,应用程序栏 Flink 。为什么会发生这种情况,我如何才能摆脱这种情况?
代码:
导航:
@Composable
fun TodoNavHost(
navController: NavHostController,
modifier: Modifier = Modifier
) {
NavHost(
navController = navController,
startDestination = TodoScreen.TodoList.name,
modifier = modifier
) {
composable(TodoScreen.TodoList.name) {
TodoListScreen(
onTodoEditClicked = { todo ->
navController.navigate("${TodoScreen.AddEditTodo.name}?todoId=${todo.id}")
},
onFabAddNewTodoClicked = {
navController.navigate(TodoScreen.AddEditTodo.name)
}
)
}
composable(
"${TodoScreen.AddEditTodo.name}?todoId={todoId}",
arguments = listOf(
navArgument("todoId") {
type = NavType.LongType
defaultValue = -1L
}
)
) {
AddEditTodoScreen(
onNavigateUp = {
navController.popBackStack()
},
onNavigateBackWithResult = { result ->
navController.navigate(TodoScreen.TodoList.name)
}
)
}
}
}
待办事项列表屏幕Scaffold
与TopAppBar
:
@Composable
fun TodoListBody(
todos: List<Todo>,
todoExpandedStates: Map<Long, Boolean>,
onTodoItemClicked: (Todo) -> Unit,
onTodoCheckedChanged: (Todo, Boolean) -> Unit,
onTodoEditClicked: (Todo) -> Unit,
onFabAddNewTodoClicked: () -> Unit,
onDeleteAllCompletedConfirmed: () -> Unit,
modifier: Modifier = Modifier,
errorSnackbarMessage: String = "",
errorSnackbarShown: Boolean = false
) {
var menuExpanded by remember { mutableStateOf(false) }
var showDeleteAllCompletedConfirmationDialog by rememberSaveable { mutableStateOf(false) }
Scaffold(
modifier,
topBar = {
TopAppBar(
title = { Text("My Todos") },
actions = {
IconButton(
onClick = { menuExpanded = !menuExpanded },
modifier = Modifier.semantics {
contentDescription = "Options Menu"
}
) {
Icon(Icons.Default.MoreVert, contentDescription = "Show menu")
}
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = { menuExpanded = false }) {
DropdownMenuItem(
onClick = {
showDeleteAllCompletedConfirmationDialog = true
menuExpanded = false
},
modifier = Modifier.semantics {
contentDescription = "Option Delete All Completed"
}) {
Text("Delete all completed")
}
}
}
)
},
[...]
添加/编辑屏幕Scaffold
与TopAppBar
:
@Composable
fun AddEditTodoBody(
todo: Todo?,
todoTitle: String,
setTitle: (String) -> Unit,
todoImportance: Boolean,
setImportance: (Boolean) -> Unit,
onSaveClick: () -> Unit,
onNavigateUp: () -> Unit,
modifier: Modifier = Modifier
) {
Scaffold(
modifier,
topBar = {
TopAppBar(
title = { Text(todo?.let { "Edit Todo" } ?: "Add Todo") },
actions = {
IconButton(onClick = onSaveClick) {
Icon(Icons.Default.Save, contentDescription = "Save Todo")
}
},
navigationIcon = {
IconButton(onClick = onNavigateUp) {
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
}
}
)
},
) { innerPadding ->
BodyContent(
todoTitle = todoTitle,
setTitle = setTitle,
todoImportance = todoImportance,
setImportance = setImportance,
modifier = Modifier.padding(innerPadding)
)
}
}
7条答案
按热度按时间ezykj2lf1#
Flink 是由
navigation-compose
库更新版本中的默认交叉淡入淡出动画引起的。现在消除它的唯一方法(不降低依赖性)是使用伴奏动画库:implementation "com.google.accompanist:accompanist-navigation-animation:0.20.0"
然后将普通
NavHost
替换为伴奏者的AnimatedNavHost
,将rememberNavController()
替换为rememberAnimatedNavController()
,并禁用过渡动画:myss37ts2#
我想我找到了解决这个问题的简单方法(适用于Compose1.4.0版)。
我的设置- Flink
我的所有屏幕都有自己的工具栏,包裹在脚手架中:
持有导航主机的主要活动定义如下:
解决方案-不眨眼!
将您的NavHost包裹在Surface中的活动中:
其余的屏幕保持不变。没有 Flink 和目的地之间的过渡动画几乎和片段一样(微妙的淡入/淡出)。到目前为止,我还没有发现任何负面影响。
kdfy810k3#
这是预期的行为。您正在为两个屏幕构建两个单独的应用程序栏,以便它们绑定到 Flink 。这不是正确的方式。正确的方式是将支架实际放在主Activity中,并将NavHost作为其内容放置。如果您希望修改应用程序栏,请创建变量来保存状态。然后从可组合对象中修改它们。理想情况下,然后存储在一个视图模型中。2这就是它在组合中是如何完成的。3通过变量。
谢谢
jucafojl4#
我遇到了同样的问题,有一个“scaffold-per-screen”架构,让我惊讶的是,帮助我的是将
androidx.navigation:navigation-compose
版本降低到2.4.0-alpha04
。x33g5p2x5#
对于较新的库
implementation "com.google.accompanist:accompanist-navigation-animation:0.24.1-alpha"
,您需要这样的AnimatedNavHost
还有
将
rememberNavController()
替换为rememberAnimatedNavController()
将
NavHost
替换为AnimatedNavHost
将
import androidx.navigation.compose.navigation
替换为import com.google.accompanist.navigation.animation.navigation
将
import androidx.navigation.compose.composable
替换为import com.google.accompanist.navigation.animation.composable
wfveoks06#
为了不 Flink (如果您有
AnimatedNavHost
,则不滑动),您应该将TopAppBar
放在Activity中,而不是NavHost
中,否则TopAppBar
只是屏幕的一部分,会像其他屏幕元素一样进行转换:padding
参数来自包含TopAppBar
的Scaffold
,您应该将其传递给NavHost
,并在屏幕中使用它,就像您在示例中所做的那样mzaanser7#
除了删除动画,您还可以更改动画,例如: