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

时间:2020-10-25 16:31:57

标签: 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
    }
...
}

我想知道如何在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, ...)
}

我想知道这是正确的方法还是有更好的方法。

我很乐意提供一些意见和建议,谢谢。

1 个答案:

答案 0 :(得分:1)

有一个名为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")
    }
}

编辑:由于您评论了您的问题与跨屏幕共享应用程序栏有关,因此必须指出,这将以您实现它的方式表现出来,例如,在下面的代码中,我会有不同的应用程序栏对于不同的屏幕,问题将得到解决,当然,这是一个非常简单的示例,在多于几个屏幕的情况下是不可行的。但是这里有关于在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
    }
}