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:每次输入变化时更新暂存的currentPhoneNumberonInputValidated:实时更新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
相关产品推荐
相关产品推荐

