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

Flutter中intl_phone_number_input组件手机号校验实现方法

intl_phone_number_input 手机号校验正确实现(适配最新v0.7+版本)

你现有代码已经搭好了输入框基础结构,只需要补全包自带的校验逻辑即可,不需要自己写正则,也不用找旧版本教程,以下是可直接复用的实现方式:


核心原理

这个包底层基于libphonenumber做了全球手机号规则适配,自带两种校验能力:

  • 输入过程中实时返回校验结果
  • 手动触发全规则校验(提交表单时用最稳)

具体实现步骤

1. 改造组件为状态组件存储必要数据

因为需要暂存用户输入的手机号对象、校验状态,原来的StatelessWidget要改成StatefulWidget,新增两个状态变量:

  • 存储当前输入的完整手机号对象:PhoneNumber? currentPhoneNumber
  • 存储实时校验结果:bool isPhoneValid = false

2. 配置组件参数打通校验逻辑

几个关键参数不要配错:

  • autoValidateMode设为AutovalidateMode.onUserInteraction:用户输入时才触发校验,不会一进页面就报错
  • ignoreBlank设为true:输入为空时不触发格式错误提示,空值逻辑提交时单独判断
  • onInputChanged:每次输入变化时更新暂存的currentPhoneNumber
  • onInputValidated:实时更新isPhoneValid状态,用来做输入时的即时提示
  • validator:和Form生态打通,返回错误文案时会自动在输入框下方显示错误提示

3. 提交时的最终校验(必加)

实时校验可能存在延迟,点提交按钮时一定要用包提供的PhoneNumberUtil做一次最终手动校验,结果100%准确。


可直接复用的完整代码

import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';

class PhoneNumberInput extends StatefulWidget {
  const PhoneNumberInput({Key? key}) : super(key: key);

  @override
  State<PhoneNumberInput> createState() => _PhoneNumberInputState();
}

class _PhoneNumberInputState extends State<PhoneNumberInput> {
  // 暂存输入的手机号对象
  PhoneNumber? currentPhoneNumber;
  // 实时校验状态
  bool isPhoneValid = false;
  // 全局校验工具实例,单例调用即可
  final PhoneNumberUtil phoneUtil = PhoneNumberUtil();

  // 提交时调用这个方法做最终校验
  Future<void> _submitForm() async {
    // 先判空
    if (currentPhoneNumber == null) {
      print("请输入手机号");
      return;
    }
    // 手动触发全规则校验
    bool finalValid = await phoneUtil.validateNumber(currentPhoneNumber!);
    if (finalValid) {
      // 校验通过,拿完整手机号走后续逻辑
      String fullPhoneNumber = currentPhoneNumber!.phoneNumber ?? "";
      print("校验通过,完整手机号:$fullPhoneNumber");
    } else {
      print("手机号格式错误,请检查");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(left: 30, top: 10, right: 30),
      padding: const EdgeInsets.only(left: 20, top: 5, bottom: 5),
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(
          color: isPhoneValid ? Colors.black12 : Colors.red, // 校验不通过边框变红
        ),
        borderRadius: BorderRadius.circular(10),
      ),
      child: Stack(
        children: [
          InternationalPhoneNumberInput(
            onInputValidated: (bool value) {
              // 更新实时校验状态
              setState(() {
                isPhoneValid = value;
              });
            },
            autoValidateMode: AutovalidateMode.onUserInteraction,
            ignoreBlank: true,
            onInputChanged: (PhoneNumber value) {
              // 每次输入更新暂存的手机号对象
              currentPhoneNumber = value;
            },
            // 表单校验器,返回字符串会自动显示错误提示
            validator: (String? value) {
              if (value == null || value.isEmpty) {
                return '请输入手机号';
              }
              if (!isPhoneValid) {
                return '手机号格式不正确';
              }
              return null;
            },
            cursorColor: Colors.black,
            formatInput: false,
            selectorConfig: const SelectorConfig(
              selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
            ),
            inputDecoration: const InputDecoration(
              border: InputBorder.none,
              hintText: 'Phone number',
              hintStyle: TextStyle(
                color: Colors.black26,
              ),
              contentPadding: EdgeInsets.only(left: -25, bottom: 15),
            ),
          ),
          // 提交按钮示例,实际开发放到表单对应的位置即可
          Positioned(
            right: 0,
            bottom: 0,
            child: ElevatedButton(
              onPressed: _submitForm,
              child: const Text("提交"),
            ),
          )
        ],
      ),
    );
  }
}

常见踩坑提醒

  • 不要自己写正则校验全球手机号,不同国家号段、长度规则差异极大,包内置的libphonenumber规则覆盖了全球所有国家/地区的合法手机号规则,准确率远高于自定义正则
  • 不要手动拼接国家码和输入内容作为完整手机号,直接用currentPhoneNumber.phoneNumber字段即可,已经自动拼接了正确的国家码
  • formatInput参数仅控制输入时是否自动添加空格/分隔符,不会影响校验逻辑,按需开关即可

内容的提问来源于stack exchange,提问作者I. Antonov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:57:12