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

Wear OS物理设备首次加载错误键盘问题求助

问题描述

我用androidx.compose.material3.OutlinedTextField实现了一个仅接受大写字符的输入框,代码如下:

val keyboardController = LocalSoftwareKeyboardController.current
var textFieldValue by remember { mutableStateOf(TextFieldValue("")) }
val focusRequester = remember {
    textFieldValue = textFieldValue.copy(selection = TextRange(textFieldValue.text.length))
    FocusRequester()
}
OutlinedTextField(
    label = {
        Text(label)
    },
    value = textFieldValue,
    onValueChange = {
        textFieldValue = it
        // handle value change...
    },
    keyboardOptions = KeyboardOptions.Default.copy(
        imeAction = ImeAction.Done,
        capitalization = KeyboardCapitalization.Characters,
        autoCorrect = false
    ),
    keyboardActions = KeyboardActions(onDone = {
        keyboardController?.hide()
        // handle done
    }),
    modifier = Modifier
        .fillMaxWidth()
        .padding(bottom = 16.dp)
        .focusRequester(focusRequester)
)

这段代码在模拟器上运行正常,但在Galaxy Watch 6 Classic设备上,首次唤起键盘时是小写模式,且输入框无法输入内容;关闭键盘后再次唤起则一切正常。请问我哪里操作错了?

问题分析与修复

问题出在focusRequester的初始化代码里——在remember块内直接修改textFieldValue的状态,这会干扰Compose的状态初始化流程,尤其是Wear OS设备上,键盘与输入框的状态同步逻辑对这种异常状态变更更敏感。

修复步骤:

  • 移除remember块内的状态修改:把调整光标位置的逻辑移到合适时机,比如输入框获取焦点时。
  • 强制输入内容转为大写:仅靠键盘大写设置不够可靠,在onValueChange里直接把输入内容转为大写,确保输入框始终只有大写字符。
  • 优化焦点请求逻辑:如果需要自动请求焦点,用LaunchedEffect配合focusRequester,避免在初始化阶段修改状态。

修改后的代码示例:

val keyboardController = LocalSoftwareKeyboardController.current
var textFieldValue by remember { mutableStateOf(TextFieldValue("")) }
val focusRequester = remember { FocusRequester() }

// 自动请求焦点(按需使用)
LaunchedEffect(Unit) {
    focusRequester.requestFocus()
}

OutlinedTextField(
    label = { Text(label) },
    value = textFieldValue,
    onValueChange = { newValue ->
        // 强制转为大写,同时保留光标位置
        val upperCaseText = newValue.text.uppercase()
        // 适配光标位置:原光标在末尾则移到新文本末尾,否则保留原位置
        val newSelection = if (newValue.selection.end == newValue.text.length) {
            TextRange(upperCaseText.length)
        } else {
            newValue.selection
        }
        textFieldValue = TextFieldValue(upperCaseText, newSelection)
        // handle value change...
    },
    keyboardOptions = KeyboardOptions.Default.copy(
        imeAction = ImeAction.Done,
        capitalization = KeyboardCapitalization.Characters,
        autoCorrect = false
    ),
    keyboardActions = KeyboardActions(onDone = {
        keyboardController?.hide()
        // handle done
    }),
    modifier = Modifier
        .fillMaxWidth()
        .padding(bottom = 16.dp)
        .focusRequester(focusRequester)
)

额外说明:

  • Wear OS的系统键盘对状态变更的响应和手机/模拟器存在差异,初始化阶段的状态突变容易导致键盘与输入框状态不同步。
  • 在onValueChange中强制转大写是更可靠的方案,即使键盘未按预期切换到大写模式,输入内容也会自动转为大写,符合功能需求。

内容的提问来源于stack exchange,提问作者iMan Biglari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:33:31