Я пытаюсь реализовать собственный диалог Jetpack Compose, который содержит два элемента с собственным привязанным DropdownMenu:
Строка заголовка со значком вниз, который должен вызывать меню при нажатии.
OutlinedTextField, который должен автоматически запускать меню предложений, когда пользователь вводит более 3 символов.
Проблема: Несмотря на то, что каждый элемент заключен в блок, который служит привязкой, DropdownMenu не отображается под соответствующим элементом. Вместо этого он игнорирует иерархию макета и отображает верхний левый угол диалогового окна (или экрана). Что я пробовал:
Обертывание IconButton и TextField в отдельные контейнеры Box.
Использование DropdownMenu внутри того же родительского элемента, что и триггерный элемент.
Тестирование с помощью PopupProperties(focusable = false).
Ожидаемый результат: Каждое меню должно быть привязано к соответствующему триггеру (значку или текстовому полю) в макете диалогового окна.
Вот мой исходный код
Я пытаюсь реализовать собственный диалог [b]Jetpack Compose[/b], который содержит два элемента с собственным привязанным DropdownMenu: [list] [*]Строка заголовка со значком вниз, который должен вызывать меню при нажатии.
[*]OutlinedTextField, который должен автоматически запускать меню предложений, когда пользователь вводит более 3 символов.
[/list] [b]Проблема:[/b] Несмотря на то, что каждый элемент заключен в блок, который служит привязкой, DropdownMenu не отображается под соответствующим элементом. Вместо этого он игнорирует иерархию макета и отображает верхний левый угол диалогового окна (или экрана). [b]Что я пробовал:[/b] [list] [*]Обертывание IconButton и TextField в отдельные контейнеры Box.
[*]Использование DropdownMenu внутри того же родительского элемента, что и триггерный элемент.
[*]Тестирование с помощью PopupProperties(focusable = false).
[/list] [b]Ожидаемый результат:[/b] Каждое меню должно быть привязано к соответствующему триггеру (значку или текстовому полю) в макете диалогового окна. Вот мой исходный код [code]@Composable fun CustomComposeDialog(onDismiss: () -> Unit) { var textInput1 by remember { mutableStateOf("") } var textInput2 by remember { mutableStateOf("") }
// Independent states for two different menus var headerMenuExpanded by remember { mutableStateOf(false) } val textFieldMenuExpanded = textInput1.length > 3
Dialog(onDismissRequest = onDismiss) { // The container for the dialog content Surface( shape = RoundedCornerShape(16.dp), color = MaterialTheme.colorScheme.surface, modifier = Modifier.fillMaxWidth().padding(16.dp) ) { Column( modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Text( text = "Custom Entry", style = MaterialTheme.typography.headlineSmall )
// --- 2. First Text Field & its Anchored Menu --- Box { OutlinedTextField( value = textInput1, onValueChange = { textInput1 = it }, label = { Text("Search or Type...") }, modifier = Modifier.fillMaxWidth() )
// This menu anchors specifically to the TextField Box DropdownMenu( expanded = textFieldMenuExpanded, onDismissRequest = { /* Controlled by text length */ }, // Focusable false allows the user to keep typing while menu is open properties = androidx.compose.ui.window.PopupProperties(focusable = false) ) { val suggestions = listOf("Result 1", "Result 2", "Result 3") suggestions.forEach { suggestion -> DropdownMenuItem( text = { Text(suggestion) }, onClick = { textInput1 = suggestion // Note: In a real app, you'd reset a flag here to hide it } ) } } }
// --- 3. Second Text Field --- OutlinedTextField( value = textInput2, onValueChange = { textInput2 = it }, label = { Text("Additional Notes") }, modifier = Modifier.fillMaxWidth() )