I need remove the elevation/shadow from dropdown menu, like right image:
My menu:
DropdownMenu(
expanded = mExpanded,
onDismissRequest = { mExpanded = false },
modifier = Modifier
.width(with(LocalDensity.current){mTextFieldSize.width.toDp()})
) {
mCities.forEach { label ->
DropdownMenuItem(onClick = {
mSelectedText = label
mExpanded = false
}) {
Text(text = label)
}
}
}
Based on answer: How to add elevation just in the bottom of an element? Jetpack Compose you can wrap your dropdown menu in a Surface and provide the elevation as 0.
Modified code:
Surface(
shadowElevation = 0.dp
){
DropdownMenu(
expanded = mExpanded,
onDismissRequest = { mExpanded = false },
modifier = Modifier
.width(with(LocalDensity.current){mTextFieldSize.width.toDp()})
) {
mCities.forEach { label ->
DropdownMenuItem(onClick = {
mSelectedText = label
mExpanded = false
}) {
Text(text = label)
}
}
}
}
Related
I'm trying to implement ExposedDropdownMenu - which I want to be displayed underneath TextField - when I set height of dropdown to max. 20 dp then everything is okay. But for any greater value it is always displayed above. Do you know what could be the issue here?
How it looks like:
My code:
#OptIn(ExperimentalMaterial3Api::class)
#Composable
fun TextFieldWithDropdown(
modifier: Modifier = Modifier,
textFieldState: TextFieldState,
textCallback: (String) -> Unit,
list: List<String>,
keyboardOptions: KeyboardOptions,
textStyle: TextStyle
) {
// .align(Alignment.CenterStart)
val dropDownOptions = remember { mutableStateOf(listOf<String>()) }
val textFieldValue = remember { mutableStateOf(TextFieldValue()) }
val dropDownExpanded = remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
modifier = modifier,
expanded = dropDownExpanded.value, onExpandedChange = {
dropDownExpanded.value = !dropDownExpanded.value
}) {
TextField(
modifier = Modifier
.menuAnchor()
.fillMaxWidth()
.onFocusChanged { focusState ->
if (!focusState.isFocused)
dropDownExpanded.value = false
},
value = textFieldState.text.value,
onValueChange = {
textFieldState.text.value = it
textCallback.invoke(it)
dropDownOptions.value =
list.filter { it.startsWith(textFieldState.text.value) && it != textFieldState.text.value }
.take(3)
dropDownExpanded.value = dropDownOptions.value.isNotEmpty()
},
singleLine = true,
maxLines = 1,
textStyle = textStyle,
)
ExposedDropdownMenu(
expanded = dropDownExpanded.value,
onDismissRequest = {
dropDownExpanded.value = false
},
) {
dropDownOptions.value.forEach { text ->
DropdownMenuItem(text = {
Text(text = text)
}, onClick = {
textFieldState.text.value = text
dropDownExpanded.value = false
})
}
}
}
}
I want to disable ExposedDropdownMenuBox based on a boolean variable
My code look something like this:
#Composable
private fun Title(
title: String,
onTitleChange: (String) -> Unit,
isTitleEnabled: Boolean
) {
val options = stringArrayResource(id = R.array.name_titles)
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf(title) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
enabled = isTitleEnabled,
modifier = Modifier
.fillMaxWidth()
.greyBordered(),
readOnly = true,
value = selectedOptionText,
onValueChange = { },
label = { Text(stringResource(id = R.string.input_hint_title)) },
trailingIcon = { TrailingIcon(expanded = expanded) },
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(
textColor = navyBlue,
focusedLabelColor = nightGray,
backgroundColor = white,
cursorColor = navyBlue,
trailingIconColor = nightGray,
focusedTrailingIconColor = nightGray,
focusedBorderColor = Color.Transparent,
unfocusedBorderColor = Color.Transparent,
disabledBorderColor = Color.Transparent,
)
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
options.forEach { selectionOption ->
DropdownMenuItem(
onClick = {
selectedOptionText = selectionOption
onTitleChange(selectionOption)
expanded = false
}
) {
Text(text = selectionOption)
}
}
}
}
}
So I have a compose function that contains ExposedDropdownMenuBox which contains textField and ExposedDropdownMenu, what I want to achieve is to be able to enable ExposedDropdownMenuBox whenever isTitleEnabled variable is true and not be able to expand the ExposedDropdownMenuBox whenever the isTitleEnabled variable is false.
You can use a condition inside the onExpandedChange to avoid to expand the
ExposedDropdownMenuBox. This callback is called when the user clicks on the ExposedDropdownMenuBox.
You can also remove the trailingIcon in this case.
Something like:
var isTitleEnabled by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if(isTitleEnabled) {
expanded = !expanded
}
}
) {
TextField(
enabled = isTitleEnabled,
readOnly = true,
trailingIcon = {
if (isTitleEnabled){
ExposedDropdownMenuDefaults.TrailingIcon(
expanded = expanded,
)
}
},
I have a row with a text align at the start and a image align at the end. When I press the image I'm showing a DropdownMenu, but this appear in the start of the row and I want that appear at the end of the row.
I'm trying to use Alignment.centerEnd in Modifier component but is not working.
How can I do that the popup appear at the end of the row?
#Composable
fun DropdownDemo(currentItem: CartListItems) {
var expanded by remember { mutableStateOf(false) }
Box(modifier = Modifier
.fillMaxWidth()) {
Text(modifier = Modifier.align(Alignment.TopStart),
text = currentItem.type,
color = colorResource(id = R.color.app_grey_dark),
fontSize = 12.sp)
Image(painter = painterResource(R.drawable.three_dots),
contentDescription = "more options button",
Modifier
.padding(top = 5.dp, bottom = 5.dp, start = 5.dp)
.align(Alignment.CenterEnd)
.width(24.dp)
.height(6.75.dp)
.clickable(indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = {
expanded = true
}))
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(
Color.LightGray
).align(Alignment.CenterEnd),
) {
DropdownMenuItem(onClick = { expanded = false }) {
Text("Delete")
}
DropdownMenuItem(onClick = { expanded = false }) {
Text("Save")
}
}
}
}
As documentation says:
A DropdownMenu behaves similarly to a Popup, and will use the position of the parent layout to position itself on screen.
You need to put DropdownMenu together with the caller view in a Box. In this case DropdownMenu will appear under the caller view.
var expanded by remember { mutableStateOf(false) }
Column {
Text("Some text")
Box {
Image(
painter = painterResource(R.drawable.test),
contentDescription = "more options button",
modifier = Modifier
.clickable {
expanded = true
}
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
DropdownMenuItem(onClick = { expanded = false }) {
Text("Delete")
}
DropdownMenuItem(onClick = { expanded = false }) {
Text("Save")
}
}
}
}
Use the offset parameter of the DropdownMenu().
DropdownMenu(
offset = DpOffset(x = (-66).dp, y = (-10).dp)
)
Change the x and y values. They accept both positive and negative values.
I have an image and I want to show a dropdownMenuItem when user click in the image. I was debugging the app and I can see that the code go through the DropdownDemo method but is not showing anything.
Am I doing something wrong?
Click code:
#Composable
fun Header(currentItem: CartListItems) {
var showDialog by remember { mutableStateOf(false) }
Box(Modifier.fillMaxWidth()) {
Text(modifier = Modifier.align(Alignment.TopStart),
text = currentItem.type,
color = colorResource(id = R.color.app_grey_dark),
fontSize = 12.sp)
Image(painter = painterResource(R.drawable.three_dots),
contentDescription = "more options button",
Modifier
.align(Alignment.CenterEnd)
.width(24.dp)
.height(6.75.dp)
.clickable(indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = {
showDialog = true
}))
if(showDialog) {
DropdownDemo()
showDialog = false
}
}
}
Dropmenu:
#Composable
fun DropdownDemo() {
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()
.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()
.background(
Color.Red
)
) {
items.forEachIndexed { index, s ->
DropdownMenuItem(onClick = {
selectedIndex = index
expanded = false
}) {
val disabledText = if (s == disabledValue) {
" (Disabled)"
} else {
""
}
Text(text = s + disabledText)
}
}
}
}
}
showDialog appears to be a MutableState object. Hence, when the image is clicked, it becomes true, and a recomposition is triggered, after which the conditional block is executed, displaying the DropDownMenu. However, in the very next line. You equate showDialog to false, re-trigerring a recomposition, and rendering the DropDownMenu collapsed.
Hello I can't figure out how to make a cut corners menu in jetpack compose 1.0.0-beta02. I tried wrapping the while menu with a surface but It didn't work.
TopAppBar(
modifier = Modifier
.statusBarsPadding(),
title = {
Text(text = "Title")
},
actions = {
var menuExpanded by remember { mutableStateOf(false) }
IconButton(onClick = { menuExpanded = true }) {
Icon(Icons.Default.MoreVert, contentDescription = null)
}
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = {
menuExpanded = false
},
) {
DropdownMenuItem(onClick = {}) {
Text("Item 2")
}
}
},
)
Which gives me
But I need something like this, which is rounded.
Using a M2 MaterialTheme theme, the default shape used by the DropdownMenu is defined by the
medium attribute in the shapes used in the MaterialTheme (check your theme).
val Shapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(4.dp), //<- used by `DropdownMenu`
large = RoundedCornerShape(0.dp)
)
You can change this value in your theme or you can override the medium shape only in your DropdownMenu.
Something like:
MaterialTheme(shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(16.dp))) {
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = {
menuExpanded = false
}
) {
DropdownMenuItem(onClick = {}) {
Text("Item 2")
}
DropdownMenuItem(onClick = {}) {
Text("Item 3")
}
}
}
Using a M3 MaterialTheme the default shape used by the DropdownMenu is defined by the extraSmall attribute in the shapes:
MaterialTheme(
shapes = MaterialTheme.shapes.copy(extraSmall = RoundedCornerShape(16.dp))){
//... DropdownMenu()
}