Flutter 手机号 XXX_XXXX_XXXX 格式化输入
最近在做自家产品的时候,需要用到手机号登陆,而产品要求的格式是 XXX XXXX XXXX,即中间需要有空格。Flutter 默认的输入框无法满足,需要自己写一个 InputFormatter。
效果图
代码解析
源码如下:
import 'package:flutter/services.dart';
TextInputFormatter phoneInputFormatter() {
return TextInputFormatter.withFunction((oldValue, newValue) {
String text = newValue.text;
//获取光标左边的文本
final positionStr = (text.substring(0, newValue.selection.baseOffset)).replaceAll(RegExp(r"\s+\b|\b\s"), "");
//计算格式化后的光标位置
int length = positionStr.length;
var position = 0;
if (length <= 3) {
position = length;
} else if (length <= 7) {
// 因为前面的字符串里面加了一个空格
position = length + 1;
} else if (length <= 11) {
// 因为前面的字符串里面加了两个空格
position = length + 2;
} else {
// 号码本身为 11 位数字,因多了两个空格,故为 13
position = 13;
}
//这里格式化整个输入文本
text = text.replaceAll(RegExp(r"\s+\b|\b\s"), "");
var string = "";
for (int i = 0; i < text.length; i++) {
// 这里第 4 位,与第 8 位,我们用空格填充
if (i == 3 || i == 7) {
if (text[i] != " ") {
string = string + " ";
}
}
string += text[i];
}
return TextEditingValue(
text: string,
selection: TextSelection.fromPosition(TextPosition(offset: position, affinity: TextAffinity.upstream)),
);
});
}
里面注释写得比较详细,如发现我有没说明白的地方,可以评论区留言。
使用
源码如下:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: TextField(
keyboardType: TextInputType.phone,
style: const TextStyle(fontSize: 20),
inputFormatters: [
phoneInputFormatter(),
LengthLimitingTextInputFormatter(13),
],
),
),
],
),
),
);
}
}
这里面还有一个有意思的地方就是 LengthLimitingTextInputFormatter
,这个 InputFormatter 用于限制输入的长度(比如我们这里为 13)。
此时,有朋友可能就想到了,用 TextField 属性 MaxLength 不也可以限制长度吗?确实是的,只不过用 MaxLength 的时候,输入框右下方会出现 13/13 字样,而这是我们不需要的,因此用了这个限制长度的格式化器来帮我们处理。
对于右下方的 13/13 字样,如果我们不使用 LengthLimitingTextInputFormatter
,我们也可以通过实现 TextField 中的 buildCounter 属性,来进行适当的消除。有兴趣的朋友可以去尝试尝试。
相信通过这个简单的自定义格式化器,我们也能够实现其他的一些格式化器,这篇文章就讲到这里
若朋友不嫌弃,给个关注呗,让我们共同探索互联网新技术
转载自:https://juejin.cn/post/7088154034736988190