自动完成可组合,渲染在 UI 其余部分之上

问题描述 投票:0回答:1

我正在继续开发来自 AutoComplete 可组合项的 AutoComplete 可组合项,在弹出窗口可见时无法键入

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AutoCompleteExample() {
    Scaffold(topBar = { TopAppBar(title = { Text("AutoCompleteExample") }) }) { innerPadding ->
        Column(modifier = Modifier.padding(innerPadding)) {
            val names = listOf("Tony Stark", "Steve Rogers", "Bruce Banner", "Natasha Romanoff")
            var name by remember { mutableStateOf("") }
            val aliases = listOf("Iron Man", "Captain America", "Hulk", "Black Widow")
            var alias by remember { mutableStateOf("") }

            AutoComplete(
                label = { Text("Name") },
                options = names,
                value = name,
                onValueChange = { name = it },
            )
            AutoComplete(
                value = alias,
                options = aliases,
                onValueChange = { name = it },
                label = { Text("Alias") }
            )
        }
    }
}

@Composable
fun AutoComplete(
    label: @Composable () -> Unit,
    options: List<String>,
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    isError: Boolean = false,
) {
    var expanded by remember { mutableStateOf(false) }
    var filteredOpts by remember { mutableStateOf(options) }

    Column {
        TextField(
            label = label,
            value = value,
            onValueChange = {
                onValueChange(it)
                filteredOpts = options.filter { option ->
                    option
                        .lowercase()
                        .contains(it.lowercase())
                }
                expanded = true
            },
            isError = isError,
            keyboardOptions = keyboardOptions,
            modifier = modifier
        )

        if (expanded && filteredOpts.isNotEmpty()) {
            Column(
                modifier = Modifier
                    .fillMaxWidth(),
            ) {
                filteredOpts.forEach { option ->
                    DropdownMenuItem(
                        text = { Text(text = option) },
                        onClick = {
                            onValueChange(option)
                            filteredOpts = emptyList()
                            expanded = false
                        }
                    )
                }
            }
        }
    }
}

到目前为止一切顺利。但是,当用户开始输入时。这些建议将第二个自动完成功能进一步向下推,而不是在其之上渲染。我该如何解决这个问题?

enter image description here

android autocomplete android-jetpack-compose
1个回答
0
投票

也许您应该尝试使用

Popup
来过滤结果。 我稍微改变了你的代码,它并不完美,但看看这个:

@Composable
fun AutoComplete(
    label: @Composable () -> Unit,
    options: List<String>,
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    isError: Boolean = false,
) {
    var expanded by remember { mutableStateOf(false) }
    var filteredOpts by remember { mutableStateOf(options) }

    Column {
        TextField(
            label = label,
            value = value,
            onValueChange = {
                onValueChange(it)
                filteredOpts = options.filter { option ->
                    option
                        .lowercase()
                        .contains(it.lowercase())
                }
                expanded = true
            },
            isError = isError,
            keyboardOptions = keyboardOptions,
            modifier = modifier
        )

        if (expanded && filteredOpts.isNotEmpty()) {
            Popup(
                alignment = Alignment.TopStart,
                offset = IntOffset(x = 0, y = 200),
                properties = PopupProperties(
                    excludeFromSystemGesture = true,
                ),
                // to dismiss on click outside
                onDismissRequest = {
                    filteredOpts = emptyList()
                    expanded = false
                }
            ) {
                Column(
                    modifier = Modifier
                        .clip(RoundedCornerShape(12.dp))
                ) {
                    filteredOpts.forEach { option ->

                        Box(
                            Modifier
                                .wrapContentHeight()
                                .padding(vertical = 15.dp)
                                .background(Color.White)
                                .clickable {
                                    onValueChange(option)
                                    filteredOpts = emptyList()
                                    expanded = false
                                },
                            contentAlignment = Alignment.Center
                        ) {
                            Text(text = option)
                        }
                    }
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.