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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:27:02