如何在Flutter中实现适配全场景的IP地址TextInputFormatter输入掩码
Flutter IP地址输入文本框实现方案
现有实现问题分析
你当前的代码通过逐字符判断、分隔符计数的逻辑实现格式化,缺少统一的分段校验规则,因此在输入中间段3位数字的场景下容易出现适配失效的问题。
更简洁的实现方案
核心思路
通过分段校验的方式处理输入,统一限制每个IP分段的长度和取值范围,自动插入分隔符,兼容所有合法IPv4格式。
实现代码
import 'package:flutter/services.dart'; class IpInputFormatter extends TextInputFormatter { // 可自定义分隔符,默认使用. 要换横杠修改这个值即可 final String separator = '.'; @override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { // 过滤非法字符,只保留数字和分隔符 String input = newValue.text.replaceAll(RegExp('[^0-9$separator]'), ''); List<String> segments = input.split(separator); StringBuffer outputBuffer = StringBuffer(); int cursorOffset = newValue.selection.baseOffset; for (int i = 0; i < segments.length; i++) { String segment = segments[i].trim(); // 单个分段最多保留3位数字 if (segment.length > 3) { segment = segment.substring(0, 3); } // 限制单个分段取值不超过255 if (segment.length == 3) { int? segmentNum = int.tryParse(segment); if (segmentNum != null && segmentNum > 255) { segment = '255'; } } outputBuffer.write(segment); // 前3个非空分段后自动加分隔符 if (i < 3 && segment.isNotEmpty) { // 当前分段满3位,或者用户已经输入了下一段的内容,就插入分隔符 if (segment.length == 3 || i < segments.length - 1) { outputBuffer.write(separator); // 自动插入分隔符后同步调整光标位置 if (cursorOffset >= outputBuffer.length - 1) { cursorOffset++; } } } } String outputStr = outputBuffer.toString(); // 限制总长度不超过最大IP长度 int maxLength = 3 * 4 + 3; if (outputStr.length > maxLength) { outputStr = outputStr.substring(0, maxLength); } // 处理光标越界问题 if (cursorOffset > outputStr.length) { cursorOffset = outputStr.length; } return TextEditingValue( text: outputStr, selection: TextSelection.collapsed(offset: cursorOffset), ); } }
使用方法
直接将格式化器添加到TextField的inputFormatters属性中即可:
TextField( // 数字键盘,方便输入 keyboardType: TextInputType.number, inputFormatters: [ IpInputFormatter(), ], decoration: const InputDecoration( hintText: '请输入IP地址', border: OutlineInputBorder(), ), )
方案特性
- 支持所有合法IPv4格式,包括1.1.1.1、10.100.2.3、192.168.1.1等场景
- 自动插入分隔符,也支持用户手动输入分隔符
- 自动限制每个分段取值在0-255之间,避免非法IP输入
- 光标定位逻辑完善,删除、修改内容时不会出现跳位问题
- 可自定义分隔符,修改
separator变量即可切换为-等其他分隔符
内容的提问来源于stack exchange,提问作者Isaque Neves
相关产品推荐
相关产品推荐

