MaskTextInputFormatter输入异常:插入删前位/非数字清空内容求助
解决MaskTextInputFormatter手机号格式化的两个异常问题
在使用MaskTextInputFormatter格式化手机号输入框(无论原生TextFormField还是自定义TextField)时,出现两个问题:
- 插入数字时会删除前一位字符
- 输入非数字字符时,已输入内容被全部清空
问题原因
- 掩码与状态同步冲突:使用
initialValue绑定状态值,当onChanged更新状态后,initialValue会重新传入TextFormField,导致MaskTextInputFormatter重复处理文本,引发光标位置错乱和内容异常。 - 未显式配置过滤规则:默认过滤规则可能存在兼容问题,非数字输入触发 formatter 异常处理,导致内容清空。
解决方案
1. 使用TextEditingController替代initialValue
通过控制器直接管理输入文本,避免状态同步带来的重复格式化问题。
2. 显式配置过滤规则与掩码补全方式
指定仅允许数字输入,并调整掩码补全策略,减少格式化冲突。
3. 升级插件版本
确保使用最新稳定版的mask_text_input_formatter,修复已知BUG。
修改后的代码示例
import 'package:flutter/material.dart'; import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; class MobileInputWidget extends StatefulWidget { final MobileModel mobile; // 假设的MobileModel类 const MobileInputWidget({Key? key, required this.mobile}) : super(key: key); @override State<MobileInputWidget> createState() => _MobileInputWidgetState(); } class _MobileInputWidgetState extends State<MobileInputWidget> { late final TextEditingController _mobileController; final _phoneMaskFormatter = MaskTextInputFormatter( mask: "+258 ###-##-##", filter: {"#": RegExp(r'[0-9]')}, // 显式指定仅允许数字 type: MaskAutoCompletionType.lazy, // 延迟补全掩码,仅在输入内容时显示格式符 ); @override void initState() { super.initState(); // 初始化控制器文本 _mobileController = TextEditingController(text: widget.mobile.contactNumber); } @override void dispose() { _mobileController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextFormField( controller: _mobileController, onChanged: (value) { widget.mobile.setContactNumber(value); }, inputFormatters: [_phoneMaskFormatter], keyboardType: TextInputType.phone, // 指定手机号键盘,减少非数字输入 ); } }
额外说明
- 加入
keyboardType: TextInputType.phone可以让系统弹出数字键盘,从源头减少非数字输入的可能。 MaskAutoCompletionType.lazy模式下,掩码格式符(如-)会在输入对应位置的数字后才显示,避免光标位置异常。
内容的提问来源于stack exchange,提问作者Igor L Sambo
相关产品推荐
相关产品推荐

