Flutter TextFormField清空内容后失焦问题求助
问题分析与修复方案
核心问题1:Controller重复创建触发组件重建
在Consumer的builder方法中,你每次都会新建MaskedTextController并直接赋值文本,这会导致状态更新时CustomTextFormField频繁重建,直接丢失焦点。
核心问题2:自定义FocusScope干扰焦点管理
你手动给TextFormField套了一层自定义的FocusScopeNode,这会打乱默认的焦点流转逻辑,清空文本时的焦点请求会被这个自定义FocusScope拦截。
修复步骤
1. 重构Controller的创建与更新逻辑
把控制器的创建移到builder外部,用组件状态或状态管理工具保存实例,只在值真正变化时更新文本:
// 示例:在State类中管理控制器 class _YourFormState extends State<YourFormWidget> { late MaskedTextController cedulaController; @override void initState() { super.initState(); cedulaController = MaskedTextController(mask: '000-0000000-0'); } @override void didChangeDependencies() { super.didChangeDependencies(); final formValue = context.watch<YourFormValue>(); // 仅当值不同时更新,避免不必要的组件重建 if (cedulaController.text != formValue.cedula.value) { cedulaController.text = formValue.cedula.value; } } @override Widget build(BuildContext context) { return Form( child: Column( children: [ Consumer( builder: (context, watch, _) { return CustomTextFormField( readOnly: false, label: 'Digite su número de cédula', controller: cedulaController, onChanged: (cedula) async { // 你的业务逻辑 }, ); }, ), ], ), ); } }
2. 移除多余的FocusScope配置
删除自定义的FocusScope包裹,让TextFormField使用默认的焦点管理体系:
// 修改后的CustomTextFormField核心代码 return TextFormField( focusNode: focusNode, textCapitalization: textCapitalization, onTapOutside: (event) => FocusScope.of(context).unfocus(), onChanged: (value) { onChanged?.call(value); // 用PostFrameCallback确保焦点请求在组件更新后执行 if (value.isEmpty) { WidgetsBinding.instance.addPostFrameCallback((_) { focusNode?.requestFocus(); }); } }, // 其他原有属性 );
3. 规范FocusNode的生命周期管理
如果focusNode是组件内部创建的,要在dispose方法中释放资源;如果是外部传入,避免在组件内销毁:
// 示例:在CustomTextFormField的State中管理FocusNode class _CustomTextFormFieldState extends State<CustomTextFormField> { late FocusNode _focusNode; @override void initState() { super.initState(); _focusNode = widget.focusNode ?? FocusNode(); } @override void dispose() { // 仅销毁组件内部创建的FocusNode if (widget.focusNode == null) { _focusNode.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return TextFormField( focusNode: _focusNode, // 其他属性 ); } }
内容的提问来源于stack exchange,提问作者Rickard245
相关产品推荐
相关产品推荐

