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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:15:02