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

Flutter页面切换后输入框焦点与键盘闪显消失问题排查

Flutter表单输入框焦点异常问题

问题现象

我的Flutter应用包含两个页面:

  • 表单页:带有多行文本输入框
  • 列表页:通过ListView.builder()实现横向滚动列表

出现的异常:

  • 先打开列表页,再切换到表单页时,点击输入框键盘会短暂弹出后立即消失,输入框焦点丢失,该问题需重启应用才能恢复
  • 但如果先打开表单页,输入框可正常使用
  • 尝试过调用unfocus()、用Focus组件包裹表单或列表,均无法解决问题
  • 移除列表页的ListView后,表单页恢复正常

相关代码

列表页ListView代码

_controller = ScrollController(initialScrollOffset: _leftPadding);

ListView.builder(
  controller: _controller,
  scrollDirection: Axis.horizontal,
  itemCount: null, // 此处存在问题
  itemBuilder: (context, index) {
     /// 返回Container组件的代码
     return Container(); 
  }
);

表单页TextField代码

Form(key: formKey, child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
       TextFormField(
         minLines: 10,
         maxLines: 15,
         keyboardType: TextInputType.multiline,
         textCapitalization: TextCapitalization.sentences,
         validator: validator,
       )
    ]
));

解决方案

1. 修复ListView的itemCount参数

ListView.builder的itemCount不能设为null,这会导致Flutter内部渲染状态异常,进而干扰焦点管理逻辑。根据实际场景修改:

  • 若为有限数据列表:设为数据源的长度(如data.length)
  • 若为无限滚动列表:设置一个合理的大数(如1000)

修改后的ListView代码:

_controller = ScrollController(initialScrollOffset: _leftPadding);

ListView.builder(
  controller: _controller,
  scrollDirection: Axis.horizontal,
  itemCount: 1000, // 替换为实际数据长度或合理数值
  itemBuilder: (context, index) {
     return Container(/* 你的子组件代码 */); 
  }
);

2. 正确管理ScrollController生命周期

在列表页的dispose方法中销毁ScrollController,避免控制器残留影响其他页面:

@override
void dispose() {
  _controller.dispose(); // 销毁滚动控制器
  super.dispose();
}

3. 手动管理表单输入框焦点

给TextFormField添加FocusNode,并在页面初始化时确保焦点可正常获取:

final _inputFocusNode = FocusNode();

@override
void dispose() {
  _inputFocusNode.dispose(); // 销毁焦点节点
  super.dispose();
}

// 表单部分代码
Form(key: formKey, child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
       TextFormField(
         focusNode: _inputFocusNode,
         minLines: 10,
         maxLines: 15,
         keyboardType: TextInputType.multiline,
         textCapitalization: TextCapitalization.sentences,
         validator: validator,
       )
    ]
));

4. 页面切换时清理全局焦点

在列表页离开时主动清理当前焦点,避免焦点残留:

@override
void deactivate() {
  FocusManager.instance.primaryFocus?.unfocus();
  super.deactivate();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:35:24