flutter - 验证并仅允许 TextField 中的日期和连字符 - MaskTextInputFormatter 不适用于手动更新文本
问题描述
我需要制作一个具有日期过滤器(dd-mm-yyyy)的TextField,我设法使用依赖项创建过滤器,mask_text_input_formatter: ^1.0.6
如下所示
final TextEditingController _controller = TextEditingController();
var maskFormatter = new MaskTextInputFormatter(mask: '##-##-####');
...
child: TextField(
controller: _controller,
keyboardType: TextInputType.number,
inputFormatters: [maskFormatter],
onChanged: (text) {
//
},
因此,由于我找不到将文本屏蔽为有效日期的好方法(例如,没有 31-02-9299),我决定在onChanged
回调中手动执行此操作并在某个时候更新文本,但只是使用基本 _controller.text = "1234";
显示文本"1234"
而不是"12-34"
.
可能是什么问题?
解决方案
解决方案
对于您的特定用例,您可以尝试以下解决方案:
TextField(
inputFormatters: [
WhitelistingTextInputFormatter(RegExp(r"^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$")),
],
);
解释
您无法使用mask_text_input_formatter
pub 验证所需的文本,因为它按 char 执行比较 char。因此,您只能使用正则表达式验证每个单独的字符。
要对 TextFormField 或 TextFormField 的文本执行手动验证TextField
,则需要使用TextInputFormatter。更具体地说,使用BlacklistingTextInputFormatter或WhitelistingTextInputFormatter。对于与您的问题不同的另一个示例,这里是如何限制两个点。
正则表达式取自这个答案,这个特定正则表达式的测试用例可以在这里找到。
自动插入连字符
如果您想自动插入连字符,那么您需要在onChanged中工作。这是一个简单的例子。
如果您要采用这种方法,您可以验证其中的文本,onChanged
但您还必须使用有效文本重置最近更改的无效文本,因为onChanged
在文本已更改后调用。因此,这是一种惰性验证,与BlacklistingTextInputFormatter或WhitelistingTextInputFormatter不同,后者甚至在文本被修改之前就提供了急切的验证。
推荐阅读
- android - 是否可以将 BroadcastReceiver 转换为 Coroutines?
- ios - iOS-Swift UIApplication.shared.isIdleTimerDisabled = true 在 AppStore 审核后无法正常工作
- c# - 从 void QuickFix 库方法中获取值
- javascript - 无法将 html javascript 添加到单独的 .js 文件中(我该怎么做)?
- hash - 在 Python 中使用 SHA256withRSA 进行数字签名验证失败
- javascript - Node.js / Mongoose - 撤消数据库修改错误
- extjs - 如何在树面板的 itemclick 中获取选中项目的列表
- multithreading - Winsock recv() 函数阻塞其他线程
- ruby-on-rails - RAILS 5 request.host 出错了
- android - Android GridView 0 位置问题