想象一下 Android 中工具栏的常见行为。
您在 Toolbar
中定义了一个 Activity
小部件,并且可以使用片段中的 onCreateOptionsMenu
和 onOptionsItemSelected
访问它。
但是,普通的 Jetpack Compose 不可能实现这样的事情,因为无法访问 Toolbar
的 Activity
中定义的 Scaffold
。
所以想想这个场景。您有一个 Activity
,其中定义了 Scaffold
,而 NavHost
中还有一个 Scaffold
。 NavHost
包含应用程序的所有子页面(其他可组合)。标题可以在Navigation Destination Listener中处理,剩下的就是Toolbar的Actions了。
您将如何根据您所在的当前页面/组合件更改工具栏操作?并处理对这些操作的点击?
PS : 在每个页面中使用工具栏并不是解决方案,因为在动画页面之间切换时会导致糟糕的用户体验,工具栏会在每个页面上消失并重新出现。
答案 0 :(得分:0)
您可以在 TopAppBar
级别使用 Scaffold
,并使用您当前的目的地来自定义 topBar
。
类似于:
topBar = {
// Use your logic here
val currentDestination = navBackStackEntry?.destination
if (currentDestination == ....) {
CustomAppBar()
} else {
TopAppBar(
title = { /*...*/ },
actions = {
if (currentDestination == ....) {
IconButton(onClick = { /* doSomething() */ }) {
Icon(Icons.Filled.Favorite, contentDescription = "")
}
}
IconButton(onClick = { /* doSomething() */ }) {
Icon(Icons.Filled.Add, contentDescription = "")
}
}){ //... }
}
}
否则只需在每个屏幕中使用单独的 TopAppBar
。
答案 1 :(得分:0)
我使用了一个名为 ToolbarController
的接口,其中包含回调方法,这些方法可以设置调用 scaffold 的 TopAppBar
时使用的变量的值:
@Composable
fun MyApp(){
var toolbarTitle by remember{ mutableStateOf("") }
// ToolbarController would be some interface you have defined
val toolbarController = object: ToolbarController {
override fun setTitle(title: String){
toolbarTitle = title
}
}
Scaffold(
topBar = {
TopAppBar( title = { Text(text = toolbarTitle) } )
}
){
SomeScreen(toolbarController = toolbarController)
}
}
@Composable
fun SomeScreen(
toolbarController: ToolbarController
) {
//I'm not 100% sure I need to use an effect here, but I think so...
//And I'm not sure this is the right one. It is not a coroutine I call,
//but it of course works with normal calls. Also SideEffect runs on every
//recompose according to the docs, and that's not what we want.
//https://developer.android.com/jetpack/compose/side-effects
LaunchedEffect(true){
toolbarController.setTitle("Some screen title")
}
}
编辑: 并且很容易将它用于任何工具栏属性,您可以像这样创建界面:
interface ToolbarController{
fun configToolbar(
title: String = "",
navigationIcon: IconButton? = null,
actions: List<IconButton> = listOf()
)
}
重点是您只需制作回调函数并在 LaunchedEffect 中运行它们。这是从脚手架中的可组合内设置工具栏属性的一种方法。接口的东西只是一种对这些回调进行分组的方式,所以它不会变得太乱。