在 Jetpack Compose 中创建“嵌套”菜单的更好或更简单的方法是什么?

Oma*_*mar 6 android kotlin android-jetpack android-jetpack-compose

因此,在 XML 中,您可以构建菜单项并像这样嵌套它们。

XML菜单结构


但在jetpack compose中,我无法弄清楚这是如何工作的。我已经从这里阅读并构建了一个简单的下拉菜单。但是尝试在 jetpack compose 中做与 XML 相同的事情没有多大意义。菜单是单独创建的且独立的。我正在寻找比这更简单、更好的东西。

jetpack-撰写菜单

SVP*_*SVP 5

像这样的事情怎么样?

为主菜单创建一个可组合项,并为嵌套菜单创建一个可组合项。

主菜单可组合

@Composable
fun MainMenu(
    menuSelection: MutableState<MenuSelection>,
    expandedMain: MutableState<Boolean>,
    expandedNested: MutableState<Boolean>
) {
    DropdownMenu(
        expanded = expandedMain.value,
        onDismissRequest = { expandedMain.value = false },
    ) {
        DropdownMenuItem(
            onClick = {
                expandedMain.value = false // hide main menu
                expandedNested.value = true // show nested menu
                menuSelection.value = MenuSelection.NESTED
            }
        ) {
            Text("Nested Options \u25B6")
        }

        Divider()

        DropdownMenuItem(
            onClick = {
                // close main menu
                expandedMain.value = false
                menuSelection.value = MenuSelection.SETTINGS
            }
        ) {
            Text("Settings")
        }

        Divider()

        DropdownMenuItem(
            onClick = {
                // close main menu
                expandedMain.value = false
                menuSelection.value = MenuSelection.ABOUT
            }
        ) {
            Text("About")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可组合嵌套菜单

@Composable
fun NestedMenu(
    expandedNested: MutableState<Boolean>,
    nestedMenuSelection: MutableState<NestedMenuSelection>
) {
    DropdownMenu(
        expanded = expandedNested.value,
        onDismissRequest = { expandedNested.value = false }
    ) {
        DropdownMenuItem(
            onClick = {
                // close nested menu
                expandedNested.value = false
                nestedMenuSelection.value = NestedMenuSelection.FIRST
            }
        ) {
            Text("First")
        }
        DropdownMenuItem(
            onClick = {
                // close nested menu
                expandedNested.value = false
                nestedMenuSelection.value = NestedMenuSelection.SECOND
            }
        ) {
            Text("Second")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将它们放入主下拉菜单可组合项中。

顶部栏可组合

@Composable
fun TopAppBarDropdownMenu(
    menuSelection: MutableState<MenuSelection>,
    nestedMenuSelection: MutableState<NestedMenuSelection>
) {

    val expandedMain = remember { mutableStateOf(false) }
    val expandedNested = remember { mutableStateOf(false) }

    // Three Dot icon
    Box(
        Modifier
            .wrapContentSize(Alignment.TopEnd)
    ) {
        IconButton(
            onClick = {
                // Expand the main menu on three dots icon click
                // and hide the nested menu. 
                expandedMain.value = true
                expandedNested.value = false
            }
        ) {
            Icon(
                Icons.Filled.MoreVert,
                contentDescription = "More Menu"
            )
        }
    }

    MainMenu(
        menuSelection = menuSelection,
        expandedMain = expandedMain,
        expandedNested = expandedNested
    )
    NestedMenu(
        expandedNested = expandedNested,
        nestedMenuSelection = nestedMenuSelection
    )

}
Run Code Online (Sandbox Code Playgroud)

和参数将允许根据从菜单激活的状态在主机menuSelection中执行操作。像这样的东西:nestedMenuSelectionTopAppBarDropdownMenuTopAppBarDropdownMenu

@Composable
fun MainScreen(
    /* some params */
) {
    
    val menuSelection = remember { mutableStateOf(MenuSelection.NONE) }
    val nestedMenuSelection = remember { mutableStateOf(NestedMenuSelection.DEFAULT) }
    
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = stringResource(R.string.app_name)) },
                actions = {
                    TopAppBarDropdownMenu(
                        menuSelection = menuSelection,
                        nestedMenuSelection= nestedMenuSelection
                    )
                }
            )
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

不确定这是“正确”的方法,但它对我有用。

您可以通过创建NestedMenu具有更多参数的可组合项来更轻松地实例化嵌套菜单,这将使其更容易重用。请记住,Material Design 指南建议仅在桌面上使用级联菜单

  • 这可能是目前实现这一点的唯一方法,所以我将这个问题标记为已解决。希望将来能在 android 上看到更简单的实现。 (2认同)