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

Flutter中CustomTextField点击后键盘弹出即关闭问题求助

Flutter键盘弹出后立即关闭,无法输入TextField内容

问题描述

点击自定义CustomTextField或原生TextField时,系统键盘短暂弹出后立刻关闭,完全无法输入内容。Debug Console中可看到showSoftInput()日志,但键盘无法保持弹出状态。

已尝试的解决方案

  • 依赖更新:检查并更新pubspec.yaml所有依赖,执行flutter pub get确保依赖为最新版本
  • 缓存清理:执行flutter clean清理缓存后,重新flutter pub get并flutter run构建应用
  • 设备/模拟器验证:确认模拟器配置正确,更换多台模拟器测试,问题依旧存在

相关代码

Form及CustomTextField使用代码

Form(
 key: GlobalKey<FormState>(),
 child: Column(
   children: [
     CustomTextField(
       label: 'E-mail',
       prefixIcon: Icons.email,
       keyboardType: TextInputType.emailAddress,
       controller: controller.emailController,
       validator: controller.validateEmail,
     ),
     CustomTextField(
       label: 'Senha',
       prefixIcon: Icons.password,
       isPassword: true,
       controller: controller.passwordController,
       validator: controller.validatePassword,
       keyboardType: TextInputType.text,
     ),
   ],
 ),
),

SigninController代码

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class SigninController extends GetxController {
  final RxString snackBarMessage = ''.obs;

  late TextEditingController emailController;
  late TextEditingController passwordController;

  @override
  void onInit() {
    super.onInit();
    emailController = TextEditingController();
    passwordController = TextEditingController();
  }

  @override
  void onClose() {
    emailController.dispose();
    passwordController.dispose();
    super.onClose();
  }

  String?  validateEmail(String? value) {
    if (value == null || value.isEmpty) {
      return 'Required field';
    } else if (!RegExp(r'^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7 }$')
        .hasMatch(value)) {
      return 'Invalid email';
    }
    return null;
  }

  String?  validatePassword(String? value) {
    if (value == null || value.isEmpty) {
      return 'Required field';
    } else if (value.length < 6) {
      return 'The password must be at least 6 characters long';
    }
    return null;
  }
}

额外观察

  • 即使替换为原生TextField,问题仍然存在
  • 键盘弹出瞬间Debug Console输出showSoftInput()日志

排查与解决方向

1. 检查页面是否存在不必要的重渲染

键盘弹出时页面布局变化,如果页面因setState或Rx变量更新导致频繁重渲染,会丢失TextField焦点:

  • 排查页面中是否有未正确管理的Rx变量,确认是否有变量在键盘弹出时被意外触发更新
  • 使用Flutter DevTools的Performance面板查看页面重渲染频率,确认是否存在异常重建

2. 手动管理焦点节点

绑定焦点节点并手动请求焦点,避免焦点被意外夺走:

final FocusNode _emailFocus = FocusNode();
final FocusNode _passwordFocus = FocusNode();

// 在TextField中绑定焦点
CustomTextField(
  focusNode: _emailFocus,
  // ...其他参数
)

// 点击时手动请求焦点
GestureDetector(
  onTap: () {
    FocusScope.of(context).requestFocus(_emailFocus);
  },
  child: CustomTextField(
    focusNode: _emailFocus,
    // ...其他参数
  ),
)

页面销毁时记得释放焦点节点:

@override
void dispose() {
  _emailFocus.dispose();
  _passwordFocus.dispose();
  super.dispose();
}

3. 检查Scaffold的resizeToAvoidBottomInset设置

若resizeToAvoidBottomInset设为false,键盘弹出时页面不调整布局可能导致焦点丢失:

Scaffold(
  resizeToAvoidBottomInset: true, // 确保此项为true
  // ...其他内容
)

4. 确认GetX控制器是否重复初始化

若页面中多次调用Get.put(SigninController()),会导致TextEditingController被重建,丢失焦点:

  • 确保控制器只初始化一次,后续用Get.find获取实例:
final controller = Get.find<SigninController>();

5. 排查全局焦点拦截逻辑

检查项目中是否有全局WidgetsBindingObserver或第三方库拦截焦点事件,导致键盘弹出后焦点被强制移除。


内容的提问来源于stack exchange,提问作者Anderson André

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:47:04