显示预测下拉菜单后,如何恢复OutlinedTextField的输入焦点?
问题核心是DropdownMenu默认会抢占焦点,导致OutlinedTextField失去输入状态。通过以下两处修改即可解决:
1. 禁止DropdownMenu获取焦点
给DropdownMenu添加Modifier.focusable(false),让它不再争夺输入框的焦点,确保用户能持续输入。
2. 优化焦点请求逻辑
在触发下拉菜单显示时,主动请求输入框焦点,进一步保证焦点不会丢失。
修改后的完整代码
@Composable fun CustomTextField( name: String, value: String, onChange: (String) -> Unit, predictionValues: List<String> = emptyList(), visualTransformation: VisualTransformation? = null, modifier: Modifier = Modifier, keyboardType: KeyboardType? = null, imeAction: ImeAction? = null, isEnabled: Boolean = true, keyboardActions: KeyboardActions = KeyboardActions.Default, trailingIcon: @Composable (() -> Unit)? = null ) { var expanded by remember { mutableStateOf(false) } var filteredOptions by remember { mutableStateOf<List<String>>(emptyList()) } val focusRequester = remember { FocusRequester() } var textFieldValue by remember { mutableStateOf(TextFieldValue(text = value)) } fun filterOptions(query: String) { if (query.length >= 3) { filteredOptions = predictionValues.filter { it.contains(query, ignoreCase = true) } val shouldExpand = filteredOptions.isNotEmpty() expanded = shouldExpand // 显示下拉菜单时主动请求输入框焦点 if (shouldExpand) { focusRequester.requestFocus() } } else { expanded = false } } LaunchedEffect(textFieldValue.text) { if (textFieldValue.text != value) { onChange(textFieldValue.text) } } Column(modifier = modifier.fillMaxWidth()) { OutlinedTextField( value = textFieldValue, onValueChange = { newValue -> textFieldValue = newValue filterOptions(newValue.text) }, enabled = isEnabled, modifier = Modifier .fillMaxWidth() .focusRequester(focusRequester), keyboardOptions = KeyboardOptions( keyboardType = keyboardType ?: KeyboardType.Text, imeAction = imeAction ?: ImeAction.Default ), singleLine = true, label = { Text(text = name) }, visualTransformation = visualTransformation ?: VisualTransformation.None, keyboardActions = keyboardActions, trailingIcon = { trailingIcon?.invoke() } ) DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, // 关键修改:禁止DropdownMenu获取焦点 modifier = Modifier.focusable(false) ) { filteredOptions.forEach { option -> DropdownMenuItem( text = { Text(option) }, onClick = { textFieldValue = TextFieldValue( text = option, selection = TextRange(option.length) ) expanded = false focusRequester.requestFocus() } ) } } } }
逻辑说明
Modifier.focusable(false)直接阻断了DropdownMenu的焦点获取能力,输入框能持续保持激活状态。- 在
filterOptions中添加焦点请求,是为了应对部分极端场景下的焦点偏移,进一步强化输入框的焦点持有。 - 保留点击选项后的焦点请求,确保用户选择预测内容后,输入框能立即恢复焦点,方便后续编辑操作。
内容的提问来源于stack exchange,提问作者maxxxo
相关产品推荐
相关产品推荐

