下拉菜单未与可组合对话框中文本字段的宽度对齐

发布于 2025-01-17 19:41:18 字数 3349 浏览 2 评论 0原文

DropdownMenu 可组合项未与 Dialog 可组合项内的 OutlinedTextField 的宽度对齐。它稍微向右移动。但是,将 DropdownMenu 放置在 Dialog 可组合项之外可以正常工作。我该如何解决这个问题?

输入图片此处描述

可组合下拉菜单

@Composable
fun MyDropdownMenu() {
    var mExpanded = rememberSaveable { mutableStateOf(false) }
    var mSelectedText = rememberSaveable { mutableStateOf("") }
    var mTextFieldSize = remember { mutableStateOf(Size.Zero) }
    val mCategories = listOf(
        "Produce",
        "Bakery",
        "Meats",
        "Dairy",
        "Deli",
        "Beverages",
        "Frozen"
    )
    val icon = if (mExpanded.value)
        Icons.Filled.KeyboardArrowUp
    else
        Icons.Filled.KeyboardArrowDown
    Column {

        Box {
            OutlinedTextField(
                value = mSelectedText.value,
                readOnly = true,
                onValueChange = { mSelectedText.value = it },
                label = { Text(text = "Category") },
                trailingIcon = {
                    Icon(icon, null,
                        Modifier.clickable { mExpanded.value = !mExpanded.value })
                },
                modifier = Modifier.onGloballyPositioned { coordinates ->
                mTextFieldSize.value = coordinates.size.toSize()
            }.fillMaxWidth(),
            )

            DropdownMenu(
                expanded = mExpanded.value,
                onDismissRequest = { mExpanded.value = false },
                modifier =  Modifier
                      .width(with(LocalDensity.current) { mTextFieldSize.value.width.toDp()})
            ) {
                mCategories.forEach { label ->
                    DropdownMenuItem(onClick = {
                        mSelectedText.value = label
                        mExpanded.value = false
                    }) {
                        Text(text = label)
                    }
                }
            }

        }
    }


}

可组合对话框

@Composable
fun AddItemDialog(
    onConfirmClicked: () -> Unit,
    onDismiss: () -> Unit,
) {
    Dialog(
        onDismissRequest = onDismiss
    ) {
        Surface(
            shape = MaterialTheme.shapes.medium,
            color = MaterialTheme.colors.surface,
            modifier = Modifier
                .requiredWidth(LocalConfiguration.current.screenWidthDp.dp * 0.96f)
                .padding(4.dp)
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = 16.dp, bottom = 0.dp, start = 16.dp, end = 16.dp)
            ) {
                Text(text = "Add an item", style = MaterialTheme.typography.subtitle1)

                MyDropdownMenu()
                
                Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
                    TextButton(onClick = onDismiss) {
                        Text(text = "Cancel")
                    }
                    TextButton(onClick = onConfirmClicked) {
                        Text(text = "OK")
                    }
                }
            }
        }
    }
}

The DropdownMenu composable is not aligning to the width of the OutlinedTextField which is inside a Dialog composable. It is shifted slightly to the right. However, placing the DropdownMenu outside the Dialog composable works fine. How can I fix this?

enter image description here

DropdownMenu Composable

@Composable
fun MyDropdownMenu() {
    var mExpanded = rememberSaveable { mutableStateOf(false) }
    var mSelectedText = rememberSaveable { mutableStateOf("") }
    var mTextFieldSize = remember { mutableStateOf(Size.Zero) }
    val mCategories = listOf(
        "Produce",
        "Bakery",
        "Meats",
        "Dairy",
        "Deli",
        "Beverages",
        "Frozen"
    )
    val icon = if (mExpanded.value)
        Icons.Filled.KeyboardArrowUp
    else
        Icons.Filled.KeyboardArrowDown
    Column {

        Box {
            OutlinedTextField(
                value = mSelectedText.value,
                readOnly = true,
                onValueChange = { mSelectedText.value = it },
                label = { Text(text = "Category") },
                trailingIcon = {
                    Icon(icon, null,
                        Modifier.clickable { mExpanded.value = !mExpanded.value })
                },
                modifier = Modifier.onGloballyPositioned { coordinates ->
                mTextFieldSize.value = coordinates.size.toSize()
            }.fillMaxWidth(),
            )

            DropdownMenu(
                expanded = mExpanded.value,
                onDismissRequest = { mExpanded.value = false },
                modifier =  Modifier
                      .width(with(LocalDensity.current) { mTextFieldSize.value.width.toDp()})
            ) {
                mCategories.forEach { label ->
                    DropdownMenuItem(onClick = {
                        mSelectedText.value = label
                        mExpanded.value = false
                    }) {
                        Text(text = label)
                    }
                }
            }

        }
    }


}

Dialog Composable

@Composable
fun AddItemDialog(
    onConfirmClicked: () -> Unit,
    onDismiss: () -> Unit,
) {
    Dialog(
        onDismissRequest = onDismiss
    ) {
        Surface(
            shape = MaterialTheme.shapes.medium,
            color = MaterialTheme.colors.surface,
            modifier = Modifier
                .requiredWidth(LocalConfiguration.current.screenWidthDp.dp * 0.96f)
                .padding(4.dp)
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = 16.dp, bottom = 0.dp, start = 16.dp, end = 16.dp)
            ) {
                Text(text = "Add an item", style = MaterialTheme.typography.subtitle1)

                MyDropdownMenu()
                
                Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
                    TextButton(onClick = onDismiss) {
                        Text(text = "Cancel")
                    }
                    TextButton(onClick = onConfirmClicked) {
                        Text(text = "OK")
                    }
                }
            }
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

双手揣兜 2025-01-24 19:41:18

此错误与您尝试使用 Modifier.requiredWidth 强制 Dialog 大于预期有关。从视觉上看它是有效的,但是 DropdownMenu 使用警报窗口大小进行布局,并且该大小小于您绘制的视图。

实际上还有另一种方法可以使对话框视图占据整个宽度(除了小填充之外),而不会导致此错误:

Dialog(
    onDismissRequest = {  },
    properties = DialogProperties(usePlatformDefaultWidth = false),
) {

This bug is related to the fact that you're trying to force Dialog to be bigger than it's expected with Modifier.requiredWidth. Visually it works, but DropdownMenu uses alert window size to layout, and this size is smaller than your drawn view.

There is actually another way to make the dialog view take up the entire width (except for a small padding) that does not cause this bug:

Dialog(
    onDismissRequest = {  },
    properties = DialogProperties(usePlatformDefaultWidth = false),
) {
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文