You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

显示预测下拉菜单后,如何恢复OutlinedTextField的输入焦点?

解决DropdownMenu显示后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:37:30