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

如何在Flutter中根据身份证号文本框自动填充出生日期文本框?

问题描述

我希望实现这样的功能:当输入身份证号时,出生日期文本框能自动填充对应的日期。例如输入身份证号901201,出生日期文本框应显示01-12-1990。我是Flutter新手,从未开发过此类功能,附上我的部分代码,请求帮助完成该功能的实现。

if (_idNumber.text.isEmpty) {
        createToast(_fToast, false, "ID number is empty");
        return;
      } else {
        var year = 0;
        var id= _icNumber.text;
        var x = int.parse(id.substring(0, 2));
        var month = id.substring(2, 4);
        var day = id.substring(4, 6);
        if (x < 10) {
          year = x + 2000;
        } else {
          year = x + 1900;
        }
        var dob = DateTime(year, int.parse(month), int.parse(day));
        final yr = DateTime.now().year - dob.year;
        if ((yr - 1) < 18) {
          );
          return;
        }
      }


Widget dateOfBirth(  
  ) =>
      Row(
        children: [
          SizedBox(
            width: 60,
            child: TextFormField(
               inputFormatters: <TextInputFormatter>[
                FilteringTextInputFormatter.digitsOnly,
                LengthLimitingTextInputFormatter(2),
              ],
             onChanged: (value) {
                _dobDay.text = value;
              },
              onSaved: (value) {
                _dobDay.text = value!;
              },
              maxLines: 1,
              style: const TextStyle(
                  color: Color(0xFF0D212D), height: 1.4, fontSize: 15),
              decoration: const InputDecoration(
                hintText: "DD",
                isDense: true,
                contentPadding: EdgeInsets.all(13.5),
                border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black12)),
                enabledBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
                focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
              ),
            ),
          ),
          const Text(" / "),
          SizedBox(
            width: 60,
            child: TextFormField(
              inputFormatters: <TextInputFormatter>[
                FilteringTextInputFormatter.digitsOnly,
                LengthLimitingTextInputFormatter(2),
              ],
              onChanged: (value) {
                _dobMonth.text = value;
              },
              onSaved: (value) {
                _dobMonth.text = value!;
              },
              maxLines: 1,
              style: const TextStyle(
                  color: Color(0xFF0D212D), height: 1.4, fontSize: 15),
              decoration: const InputDecoration(
                hintText: "MM",
                isDense: true,
                contentPadding: EdgeInsets.all(13.5),
                border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black12)),
                enabledBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
                focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
              ),
            ),
          ),
          const Text(" / "),
          SizedBox(
            width: 100,
            child: TextFormField(
              inputFormatters: <TextInputFormatter>[
                FilteringTextInputFormatter.digitsOnly,
                LengthLimitingTextInputFormatter(4),
              ],
              onChanged: (value) {
                _dobYear.text = value;
              },
              onSaved: (value) {
                _dobYear.text = value!;
              },
              maxLines: 1,
              style: const TextStyle(
                  color: Color(0xFF0D212D), height: 1.4, fontSize: 15),
              decoration: const InputDecoration(
                hintText: "YYYY",
                isDense: true,
                contentPadding: EdgeInsets.all(13.5),
                border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black12)),
                enabledBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
                focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(width: 1, color: Colors.black12)),
              ),
            ),
          ),
        ],
      );
解决方案

1. 初始化文本控制器

在你的State类中先完成所有TextEditingController的初始化和销毁,避免内存泄漏:

class _YourWidgetState extends State<YourWidget> {
  final TextEditingController _idNumber = TextEditingController();
  final TextEditingController _dobDay = TextEditingController();
  final TextEditingController _dobMonth = TextEditingController();
  final TextEditingController _dobYear = TextEditingController();

  @override
  void dispose() {
    _idNumber.dispose();
    _dobDay.dispose();
    _dobMonth.dispose();
    _dobYear.dispose();
    super.dispose();
  }

  // 后续逻辑代码...
}

2. 给身份证输入框添加自动触发逻辑

给身份证号的TextFormField绑定控制器,并添加onChanged回调,当输入长度达到6位时自动解析填充日期:

TextFormField(
  controller: _idNumber,
  inputFormatters: <TextInputFormatter>[
    FilteringTextInputFormatter.digitsOnly,
    LengthLimitingTextInputFormatter(6),
  ],
  onChanged: (value) {
    if (value.length == 6) {
      parseAndFillDOB(value);
    }
  },
  decoration: const InputDecoration(
    hintText: "输入身份证号前6位",
  ),
)

3. 实现解析与填充函数

修正你原代码中的语法错误,完成完整的日期解析和填充逻辑:

void parseAndFillDOB(String idPart) {
  // 提取身份证号中的日期片段
  final String yearSuffix = idPart.substring(0, 2);
  final String month = idPart.substring(2, 4);
  final String day = idPart.substring(4, 6);

  // 计算完整年份
  int year = int.parse(yearSuffix);
  year = year < 10 ? year + 2000 : year + 1900;

  // 填充出生日期输入框
  _dobDay.text = day;
  _dobMonth.text = month;
  _dobYear.text = year.toString();

  // 可选:年龄验证逻辑
  final dob = DateTime(year, int.parse(month), int.parse(day));
  final age = DateTime.now().year - dob.year;
  if (age < 18) {
    createToast(_fToast, false, "年龄未满18岁");
  }
}

4. 绑定日期输入框的控制器

给dateOfBirth组件中的每个TextFormField添加上对应的控制器,确保能接收填充的内容:
以日输入框为例:

SizedBox(
  width: 60,
  child: TextFormField(
    controller: _dobDay, // 绑定控制器
    inputFormatters: <TextInputFormatter>[
      FilteringTextInputFormatter.digitsOnly,
      LengthLimitingTextInputFormatter(2),
    ],
    onChanged: (value) {
      _dobDay.text = value;
    },
    // 其他原有属性不变...
  ),
)

月和年输入框同理,分别绑定_dobMonth和_dobYear控制器。

完成以上步骤后,当你在身份证输入框输入6位数字(如901201),出生日期的三个输入框会自动填充为01(日)、12(月)、1990(年),满足你的需求。


内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:32:06