如何在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
相关产品推荐
相关产品推荐

