如何更改 Jetpack Compose 中的 AppBar 菜单?

Arc*_*nes 9 android android-jetpack-compose

我想知道如何更改Jetpack Compose.

Fragment世界上实现这一目标需要做这样的事情:

class SampleFragment : Fragment() {
    override fun onCreate(context: Context) {
        super.onCreate(context)
        setHasOptionsMenu(true)
    }

    // Set the R.menu.sampleMenu in the AppBar
    override fun onCreateOptionsMenu(menu: Menu) {
        ...
        menuInflater.inflate(R.menu.sampleMenu, menu)
    }

    // To handle clicks on the menu
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Check id of menu item and process as follow
    }
...
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何在 Compose 中做同样的事情。我在想:

// Have a top level state which could be set 
var menu by remember { mutableStateOf(emptyList<Menu>()) }

....
TopAppBar {
    ....
    menu.forEach {
        TextButton(...)
    }
}

....

//and then on my content ill set the `menu` to a value
onCommit {
    menu = listOf(Menu1, Menu2, Menu3, ...)
}
Run Code Online (Sandbox Code Playgroud)

我想知道这是否是正确的方法,或者是否有更好的方法。

我很想得到一些意见和建议,非常感谢。

Vit*_*mos 6

有一个名为 DropdownMenu 的组件,您可以在这里阅读: https: //developer.android.com/reference/kotlin/androidx/compose/material/package-summary#dropdownmenu

请注意,您不应该将其包装在按钮中,有一个名为“toggle”的参数,它将是打开菜单的按钮。

还有一个 DropdownMenuItem,其样式由 Material Design 规范定义: https ://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#dropdownmenuitem

关于导航,我认为完全是另一回事,如果您对此有疑问,请发布其他带有详细信息的问题。

这是一个小样本:

var menuExpanded by remember { mutableStateOf(false) }
DropdownMenu(
    toggle = {
        TextButton({ menuExpanded = !menuExpanded }) {
            Text("Open menu", color = Color.White)
        }
    },
    expanded = menuExpanded,
    onDismissRequest = {
        menuExpanded = false
    },
) {
    DropdownMenuItem(onClick = {}) {
        Text("First item")
    }
    DropdownMenuItem(onClick = {}) {
        Text("Second item")
    }
    DropdownMenuItem (onClick = {}) {
        Text("Third item")
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:既然您评论说您的问题是跨屏幕共享应用程序栏,那么重要的是要指出,这将按照您实现它的方式运行,例如,在下面的代码中,我将为不同的屏幕提供不同的应用程序栏问题就会得到解决,当然,这是一个非常简单的示例,对于多个屏幕来说是不可行的。但是,有一些关于在 Compose 中处理导航的内容,如果您对此有疑问,您可以提出其他问题,以确定您需要的范围。

val currentScreen by viewModel.currentScreen.observeAsState(Screen.HOME)
when (currentScreen) {
    Screen.HOME -> Scaffold(/* topBar = ... */) {
        // Home body
    }
    Screen.PROFILE -> Scaffold(/* topBar = ... */) {
        // Profile body
    }
    Screen.CHAT -> Scaffold(/* topBar = ... */) {
        // Chat body
    }
}
Run Code Online (Sandbox Code Playgroud)