Flutter中如何实现输入时不消失的手机号输入框掩码?
Flutter 实现常驻不消失的手机号输入掩码
完全可以实现,不需要额外引入第三方插件,核心是自定义文本输入格式化器,强制输入内容始终匹配预设的掩码规则,让格式分隔符常驻、占位内容随用户输入逐步替换。
实现思路
- 预设手机号掩码规则:国内手机号通用格式为
### #### ####(# 为数字占位位,空格为固定格式分隔符,全程不消失) - 重写
TextInputFormatter的formatEditUpdate方法,每次输入变化时自动补全固定分隔符、过滤非法输入、保证光标位置正确 - 未输入的占位位通过文字样式设为灰色,已输入内容用常规文本颜色,视觉上达到占位符逐步替换的效果
完整可运行代码示例
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class PermanentPhoneMaskFormatter extends TextInputFormatter { static const mask = '### #### ####'; static const separator = ' '; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue) { // 过滤非数字输入 final inputDigits = newValue.text.replaceAll(RegExp(r'[^0-9]'), ''); // 限制最大输入长度为11位手机号 if (inputDigits.length > 11) return oldValue; final buffer = StringBuffer(); int inputIndex = 0; // 逐位拼接掩码,固定分隔符自动补全 for (int i = 0; i < mask.length; i++) { if (inputIndex >= inputDigits.length) break; if (mask[i] == separator) { buffer.write(separator); } else { buffer.write(inputDigits[inputIndex]); inputIndex++; } } final formattedText = buffer.toString(); return TextEditingValue( text: formattedText, // 光标始终保持在输入内容末尾 selection: TextSelection.collapsed(offset: formattedText.length), ); } } // 组件调用示例 class PhoneInputPage extends StatelessWidget { const PhoneInputPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('手机号输入测试')), body: Padding( padding: const EdgeInsets.all(16.0), child: Stack( alignment: Alignment.centerLeft, children: [ // 底层常驻掩码占位,未输入位显示灰色 Text( '___ ____ ____', style: TextStyle( fontSize: 16, color: Colors.grey[300], letterSpacing: 1.2, ), ), // 上层实际输入框 TextField( keyboardType: TextInputType.phone, inputFormatters: [PermanentPhoneMaskFormatter()], style: const TextStyle( fontSize: 16, color: Colors.black, letterSpacing: 1.2, ), decoration: const InputDecoration( border: InputBorder.none, counterText: '', filled: false, ), ), ], ), ), ); } }
交互效果说明
- 初始状态下显示灰色完整掩码占位
- 用户输入数字时,数字从左到右依次替换对应位置的占位符,分隔空格始终保留,不会被输入/删除操作影响
- 自动过滤非数字内容,输入到11位手机号后无法继续输入
- 退格删除时只会删除已输入的数字,固定分隔符自动保留,不会出现格式错乱
如果需要调整掩码格式(比如改成带区号的格式、银行卡号格式),只需要修改
PermanentPhoneMaskFormatter里的mask规则即可,逻辑通用。
内容的提问来源于stack exchange,提问作者shamiwizard
相关产品推荐
相关产品推荐

