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

Flutter:TextField焦点回退问题排查与修复请求

修复OTP输入框删除键回退问题

针对你遇到的两个问题,我们可以通过监听键盘事件和调整输入框内容变化逻辑来解决:

核心修改点

  1. 处理空输入框删除键触发:添加onKeyEvent监听删除键按下事件,当当前输入框为空时,主动将焦点移至上一个输入框。
  2. 简化内容变化逻辑:优化onChanged回调,确保输入框内容从有变为无时,正确触发焦点回退。
  3. 修正索引判断:适配6个输入框的索引范围(0-5),确保最后一个输入框输入内容后正确失焦。

修复后的完整代码

class VerificationTextFields extends StatelessWidget {
  final TextEditingController controller;
  final int index;
  final bool isOTPVerificationScreen;
  final Function(bool) callback;

  final AppColors appColors = injector<AppColors>();

  VerificationTextFields(
    this.controller,
    this.index,
    this.callback, {
    this.isOTPVerificationScreen = false,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 48,
      width: isOTPVerificationScreen ? 38 : 48,
      child: TextField(
        autofocus: false,
        textAlign: TextAlign.center,
        textAlignVertical: TextAlignVertical.bottom,
        keyboardType: TextInputType.number,
        controller: controller,
        maxLength: 1,
        cursorColor: appColors.blackVariant,
        style: Theme.of(context).textTheme.titleLarge,
        decoration: InputDecoration(
          filled: false,
          counterText: '',
          enabledBorder: Theme.of(context)
              .inputDecorationTheme
              .enabledBorder
              ?.copyWith(
                  borderSide:
                      BorderSide(width: 1.5, color: appColors.grayVariant)),
          focusedBorder: Theme.of(context)
              .inputDecorationTheme
              .enabledBorder
              ?.copyWith(
                  borderSide:
                      BorderSide(width: 1.5, color: appColors.blackVariant)),
        ),
        onChanged: (value) {
          if (value.isNotEmpty) {
            // 输入内容后跳转至下一个输入框
            if (index < 5) {
              FocusScope.of(context).nextFocus();
            } else {
              FocusScope.of(context).unfocus();
              callback(true);
            }
          } else {
            // 内容清空后跳转至上一个输入框
            if (index > 0) {
              FocusScope.of(context).previousFocus();
            } else {
              FocusScope.of(context).unfocus();
              callback(false);
            }
          }
        },
        onKeyEvent: (node, event) {
          // 监听删除键按下,当前输入框为空时跳转至上一个
          if (event.logicalKey == LogicalKeyboardKey.backspace &&
              event is KeyDownEvent &&
              controller.text.isEmpty) {
            if (index > 0) {
              FocusScope.of(context).previousFocus();
            }
            return KeyEventResult.handled;
          }
          return KeyEventResult.ignored;
        },
      ),
    );
  }
}

效果验证

  • 当处于第4个空输入框时,按下删除键,焦点会自动跳转到第3个输入框。
  • 所有输入框填满后,点击任意输入框删除内容,焦点会自动回退到上一个输入框;若删除第一个输入框内容,则直接失焦。

内容的提问来源于stack exchange,提问作者Naveen Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:26:08