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

键盘弹出时TextFormField焦点失效且被遮挡,如何解决?

问题描述

我有一个TextFormField,上方有一个存储其输入值的List。现在遇到两个问题:

  1. 向List添加条目后,TextFormField被键盘遮挡
  2. 调用FocusScope.of(context).requestFocus(focusNode)无法维持输入框焦点

我的TextFormField代码如下:

TextFormField(
      cursorColor: Colors.black,             
      onFieldSubmitted: (value) {
          FocusScope.of(context).requestFocus(focusNode); // 这行代码不起作用
      },
      style: new TextStyle(
        fontSize: 15.0,
        fontFamily: "Roboto",
        fontWeight: FontWeight.w400,
        color: darkGreyColor,
      ),
      controller: _textFieldController,

      keyboardType: TextInputType.text,
      focusNode: focusNode,
      textInputAction: TextInputAction.done,
      onChanged: (text) {
      },
      inputFormatters: [
        new LengthLimitingTextInputFormatter(200),
      ],
      onSaved: (String? val) {
      },
    ),

预期效果:输入框始终显示在键盘上方,提交输入内容后,输入框保持焦点并清空内容,方便继续输入
当前效果:输入框被键盘遮挡,提交后输入框焦点丢失,无法继续连续输入


解决方案

1. 修复输入框被键盘遮挡问题

用SingleChildScrollView包裹页面所有内容(List + TextFormField),并动态适配键盘高度:

SingleChildScrollView(
  padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: Column(
    children: [
      // 你的List渲染组件
      ..._listItems.map((item) => Text(item)).toList(),
      // 你的TextFormField
      _buildTextFormField(),
    ],
  ),
)

同时确保Scaffold的resizeToAvoidBottomInset保持默认的true(如果手动修改过需恢复):

Scaffold(
  resizeToAvoidBottomInset: true,
  body: // ...上述SingleChildScrollView
)

2. 修复焦点无法维持问题

提交后延迟请求焦点,避免页面布局刷新覆盖焦点操作,同时清空输入框:

onFieldSubmitted: (value) {
  // 先执行添加条目到List的逻辑
  setState(() {
    _listItems.add(value);
  });
  // 清空输入框
  _textFieldController.clear();
  // 延迟100ms请求焦点,等待布局完成
  Future.delayed(const Duration(milliseconds: 100), () {
    if (!focusNode.hasFocus) {
      FocusScope.of(context).requestFocus(focusNode);
    }
  });
},

另外必须保证focusNode和_textFieldController在initState中初始化,而非build方法内:

late FocusNode _focusNode;
late TextEditingController _textFieldController;
List<String> _listItems = [];

@override
void initState() {
  super.initState();
  _focusNode = FocusNode();
  _textFieldController = TextEditingController();
}

@override
void dispose() {
  _focusNode.dispose();
  _textFieldController.dispose();
  super.dispose();
}

3. 进阶优化:自动滚动到输入框

如果List条目较多,添加后输入框可能被挤出可视区域,可通过GlobalKey配合滚动确保输入框可见:

// 定义全局Key
final GlobalKey _textFieldKey = GlobalKey();

// 给TextFormField绑定Key
TextFormField(
  key: _textFieldKey,
  // ...其他属性
)

// 添加条目后执行滚动
setState(() {
  _listItems.add(value);
});
WidgetsBinding.instance.addPostFrameCallback((_) {
  Scrollable.ensureVisible(
    _textFieldKey.currentContext!,
    duration: const Duration(milliseconds: 300),
    curve: Curves.easeInOut,
  );
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:15:35