如何在Flutter的TextField/TextFormField中实现hh:mm:ss格式时间输入(无需选择器)
实现方案
你需要自定义TextInputFormatter实现输入右推补零的逻辑,不需要依赖第三方mask包,完整实现代码如下:
首先编写自定义输入格式化类:
import 'package:flutter/services.dart'; class TimeInputFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { // 只处理数字输入,过滤非数字字符 final inputDigits = newValue.text.replaceAll(RegExp(r'[^0-9]'), ''); if (inputDigits.isEmpty) { // 输入全删完返回空,显示hint文本 return newValue.copyWith( text: '', selection: const TextSelection.collapsed(offset: 0), ); } // 最多保留6位数字,对应时分秒各2位 final filteredDigits = inputDigits.padLeft(6, '0').substring(inputDigits.length > 6 ? inputDigits.length -6 : 0); // 按格式拼接冒号 final formattedText = '${filteredDigits.substring(0,2)}:${filteredDigits.substring(2,4)}:${filteredDigits.substring(4,6)}'; // 光标固定在末尾,符合连续输入的交互逻辑 return TextEditingValue( text: formattedText, selection: TextSelection.collapsed(offset: formattedText.length), ); } }
然后修改你的TimeInputField组件,替换原来的mask格式化器即可:
import 'package:flutter/services.dart'; class TimeInputField extends StatefulWidget { TimeInputField({Key? key}) : super(key: key); @override _TimeInputFieldState createState() => _TimeInputFieldState(); } class _TimeInputFieldState extends State<TimeInputField> { final TextEditingController _txtTimeController = TextEditingController(); @override Widget build(BuildContext context) { return TextFormField( controller: _txtTimeController, keyboardType: TextInputType.number, decoration: const InputDecoration( hintText: '00:00:00', ), inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.digitsOnly, TimeInputFormatter(), ], // 可选:输入完成后校验时分秒合法性 validator: (value) { if (value == null || value.isEmpty) return '请输入时间'; final parts = value.split(':'); final hour = int.parse(parts[0]); final minute = int.parse(parts[1]); final second = int.parse(parts[2]); if (minute > 59 || second > 59) return '时间格式不合法'; return null; }, ); } }
逻辑说明
- 输入过程中会自动过滤所有非数字字符,仅保留数字处理
- 纯数字串不足6位时自动在左侧补零,拆分后拼接冒号实现你需要的右推输入效果,完全匹配你给出的交互示例
- 输入过程中允许分、秒数值超过60,可在提交或校验阶段再做合法性转换/提示
- 光标默认固定在输入末尾,符合连续输入的使用习惯
内容的提问来源于stack exchange,提问作者Andrey Sorokin
相关产品推荐
相关产品推荐

