简体   繁体   English

Jetpack Compose:从 DropDownItems 到 DropDownMenu 提升点击状态

[英]Jetpack Compose : Hoisitng click state from DropDownItems to DropDownMenu

What i am trying to do is to close the TopBar dropdown menu after clicking the dropdown item.我想要做的是在单击下拉项后关闭 TopBar 下拉菜单。 It can be easily done, if i am putting the dropdown items directly inside the dropdown menu.如果我将下拉项直接放在下拉菜单中,则可以轻松完成。 But here i am trying to separate it as a composable for readability.但在这里我试图将它分离为一个可组合的可读性。

Here is my TopAppBar这是我的TopAppBar

@Composable
fun TopBar(
    scope: CoroutineScope,
    scaffoldState: ScaffoldState,
    event: (AdminLaunchEvents) -> Unit,
    navController: NavHostController
) {
    val openDialog = remember { mutableStateOf(false) }
    TopAppBar(
        title = {
            Text(text = "Main App Admin Area", fontSize = 18.sp)
        },
        actions = {
            OverflowMenu() {
                SettingsDropDownItem(onClick = {})
                ModeDropDownItem(onClick = {})
                LogoutDropDownItem(onClick = {
                    openDialog.value = true
                })
            }
        },
        backgroundColor = MaterialTheme.colors.primary,
        contentColor = Color.White
    )
    if (openDialog.value) {
        LogOutComponent(openDialog = openDialog, event = event,navController = navController)
    }
}

And this is the OverFlowMenu composable which contains the DropDown Menu这是OverFlowMenu可组合的,其中包含下拉菜单

@Composable
fun OverflowMenu(content: @Composable () -> Unit) {
    var showMenu by remember { mutableStateOf(false) }

    IconButton(onClick = {
        showMenu = !showMenu
    }) {
        Icon(
            imageVector = Icons.Outlined.MoreVert,
            contentDescription = "More",
        )
    }
    DropdownMenu(
        expanded = showMenu,
        onDismissRequest = { showMenu = false }
    ) {
        content()        
    }
}

Now given below is the DropDownItem .现在下面给出的是DropDownItem

@Composable
fun SettingsDropDownItem(onClick: () -> Unit) {
    DropdownMenuItem(onClick = onClick) {
        Icon(
            Icons.Filled.Settings,
            contentDescription = "Settings",
            modifier = Modifier.size(24.dp)
        )
        Spacer(modifier = Modifier.width(8.dp))
        Text("Settings")
    }
}

What i am trying to do is, when i click the SettingsDroDownItem , i need to capture the click event in the OverFlowMenu composable to make the showMenu false , so as the hide the DropdownMenu .我想要做的是,当我单击SettingsDroDownItem ,我需要在OverFlowMenu可组合中捕获单击事件以使showMenu false ,以便隐藏DropdownMenu I can get the click event in the TopAppBar , but how to get it on DropDownMenu .我可以在TopAppBar获得点击事件,但如何在DropDownMenu上获得它。

How to do that?怎么做?

  1. The first option is moving showMenu state out of OverflowMenu , as this is not the only composable which depends on the value.第一个选项是将showMenu状态移出OverflowMenu ,因为这不是唯一取决于值的可组合项。 Something like this: OverFlowMenu :像这样: OverFlowMenu

     @Composable fun OverflowMenu(showMenu: Bool, setShowMenu: (Bool) -> Unit, content: @Composable () -> Unit) { // ... }

    TopBar : TopBar

     actions = { var (showMenu, setShowMenu) = remember { mutableStateOf(false) } OverflowMenu(showMenu, setShowMenu) { SettingsDropDownItem(onClick = { openDialog.value = true setShowMenu(false) }) } },
  2. An other options is creating something like OverflowMenuScope , and running SettingsDropDownItem on this scope so it can close the menu itself: OverflowMenu :另一个选项是创建类似OverflowMenuScope东西,并在这个范围上运行SettingsDropDownItem以便它可以关闭菜单本身: OverflowMenu

     interface OverflowMenuScope { fun closeMenu() } @Composable fun OverflowMenu(content: @Composable OverflowMenuScope.() -> Unit) { var showMenu by remember { mutableStateOf(false) } val scope = remember { object: OverflowMenuScope { override fun closeMenu() { showMenu = false } } } //... DropdownMenu( expanded = showMenu, onDismissRequest = { showMenu = false } ) { scope.content() } }

    SettingsDropDownItem : SettingsDropDownItem

     @Composable fun OverflowMenuScope.SettingsDropDownItem(onClick: () -> Unit) { DropdownMenuItem(onClick = { closeMenu() onClick() }) { Icon( Icons.Filled.Settings, contentDescription = "Settings", modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) Text("Settings") } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM