5

I'm trying to follow this tutorial

But I need more customized UI regarding the dropdown list. I need to make the popup background rounded. But when I added .clip(RoundedCornerShape(20)) into the DropdownMenu's modifier, it still have the white background

Bellow is my test composable code:

@ExperimentalFoundationApi
@ExperimentalCoilApi
@Composable
fun TestScreen(
   navigator: AppNavigator,
) {
    var expanded by remember { mutableStateOf(false) }
    val items = listOf("A", "B", "C", "D", "E", "F")
    val disabledValue = "B"
    var selectedIndex by remember { mutableStateOf(0) }
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Cyan)
            .padding(top = 70.dp)
            .wrapContentSize(Alignment.TopStart)
    ) {
        Text(
            items[selectedIndex],
            modifier = Modifier
                .fillMaxWidth()
                .clickable(onClick = { expanded = true })
                .background(
                    Color.Gray
                )
        )
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            modifier = Modifier
                .fillMaxWidth()
                .clip(RoundedCornerShape(20))
                .background(
                    Color.Red
                )
        ) {
            items.forEachIndexed { index, s ->
                DropdownMenuItem(onClick = {
                    selectedIndex = index
                    expanded = false
                }) {
                    Text(text = s)
                }
            }
        }
    }
}

I can still clip, draw border, set background color. But the white background is just still there.

I tried to look into the source code of DropDownMenu but I can't seems to find the place for it. I'm new to Jetpack Compose, so maybe I missed something.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Tran Hoai Nam
  • 1,273
  • 2
  • 18
  • 35

2 Answers2

9

DropdownMenu looks like this because of default Card parameters.

You can change MaterialTheme related parameters for the whole app or override them for a single view like this:

MaterialTheme(
    colors = MaterialTheme.colors.copy(surface = Color.Red),
    shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(20))
) {
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false },
        modifier = Modifier
            .fillMaxWidth()
    ) {
        // ...
    }
}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • 1
    @TranHoaiNam I've showed you where the `Card` is used inside `DropdownMenu`. This component has default parameters for shape and background color, which are taken from `MaterialTheme`. With my solution you're providing different values, same as you do in your theme, but in this case you can apply to only one composable instead of the whole app. – Phil Dukhov Apr 05 '22 at 09:39
  • Duckhov, just one more "simple" question. The `Card` itself have the elevation value, but it's a private field inside the file you just showed me, can I somehow override that elevation? – Tran Hoai Nam Apr 06 '22 at 11:12
  • 1
    @TranHoaiNam no, there's no easy way you can override this one. Ofc you always can copy full source code of `DropdownMenu` and change it. – Phil Dukhov Apr 06 '22 at 13:46
  • The parameter `colors` of MaterialTheme is now called `colorScheme`. – AplusKminus Jun 24 '23 at 14:54
5
implementation "androidx.compose.material3:material3:1.0.0-alpha16"

With the dependency above, you can change the DropdownMenu Background color with the Modifier

modifier = Modifier.background(Color.Blue),

@Composable
fun ListItemPopupMenu(
    menuItems: List<String>,
    onClickListeners: List<() -> Unit>,
    onDismiss: () -> Unit,
    showMenu: Boolean,
) {
    DropdownMenu(
        modifier = Modifier.background(Color.Blue),
        expanded = showMenu,
        onDismissRequest = { onDismiss() },
    ) {
        menuItems.forEachIndexed { index, item ->
            DropdownMenuItem(
                text = { Text(text = item) },
                onClick = {
                    onDismiss()
                    onClickListeners[index].invoke()
                }
            )
        }
    }
}

Here is the preview

@Preview
@Composable
fun PreviewListItemPopupMenu() {
    var expanded by remember { mutableStateOf(true) }

    ListItemPopupMenu(
        menuItems = listOf("Menu1", "Menu2"),
        onClickListeners = listOf(
            {
                // do nothing
            },
            {
                // do nothing
            }
        ),
        onDismiss = {
            expanded = false
        },
        showMenu = expanded
    )
}

enter image description here

Jeffery Ma
  • 3,051
  • 1
  • 23
  • 26