Flutter:如何实现表单年龄字段输入整数并存入列表?
解决方案
1. 重构User类,直接存储整数类型的年龄
原代码中同时维护字符串类型的age和整数类型的age1既冗余又容易引发转换异常,直接改为仅存储整数类型的年龄:
class User { String name; int age; User({this.name = '', this.age = 0}); }
2. 限制年龄输入框仅接受数字输入
修改年龄输入框的配置,指定数字键盘并添加输入过滤器,禁止非数字字符输入:
TextFormField( controller: ageController, keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], // 仅允许输入数字 autocorrect: false, maxLines: 1, validator: (value) { if (value!.isEmpty) { return '此字段为必填项'; } // 提前验证输入是否为有效整数 if (int.tryParse(value) == null) { return '请输入有效的整数年龄'; } return null; }, onSaved: (value) { // 安全转换为整数类型 user.age = int.parse(value!); }, decoration: const InputDecoration( labelText: '年龄', hintText: '年龄', labelStyle: TextStyle(decorationStyle: TextDecorationStyle.solid)), )
注意需要导入flutter/services.dart才能使用输入过滤器:
import 'package:flutter/services.dart';
3. 修正初始化与数据操作逻辑
- 初始化User对象时使用整数默认值,避免空字符串转换错误:
User user = User(name: '', age: 0);
- 调整添加、更新用户的方法,适配整数类型的年龄:
void updateForm(User user) { setState(() { User updatedUser = User( name: nameController.text, age: int.parse(ageController.text), ); userList[currentIndex] = updatedUser; }); } void addUserToList(String name, int age) { setState(() { userList.add(User(name: name, age: age)); }); }
- 修改数据表格中年龄的显示逻辑,将整数转为字符串:
DataCell( Text(user.age.toString()), ),
- 编辑用户时,将整数年龄转为字符串赋值给输入控制器:
void _updateTextControllers(User user) { setState(() { nameController.text = user.name; ageController.text = user.age.toString(); }); }
完整修改后的代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MaterialApp(home: Episode5())); class Episode5 extends StatefulWidget { const Episode5({super.key}); @override _Episode5State createState() => _Episode5State(); } class User { String name; int age; User({this.name = '', this.age = 0}); } class _Episode5State extends State<Episode5> { final TextEditingController nameController = TextEditingController(); final TextEditingController ageController = TextEditingController(); int currentIndex = 0; final form = GlobalKey<FormState>(); static final _focusNode = FocusNode(); User user = User(name: '', age: 0); List<User> userList = [ User(name: "a", age: 12), User(name: "d", age: 23), User(name: "c", age: 19), ]; @override Widget build(BuildContext context) { Widget bodyData() => DataTable( onSelectAll: (b) {}, sortColumnIndex: 0, sortAscending: true, columns: const <DataColumn>[ DataColumn(label: Text("姓名"), tooltip: "显示姓名"), DataColumn(label: Text("年龄"), tooltip: "显示年龄"), DataColumn(label: Text("修改"), tooltip: "修改数据"), DataColumn(label: Text("删除"), tooltip: "删除数据"), ], rows: userList .map( (user) => DataRow( cells: [ DataCell( Text(user.name), ), DataCell( Text(user.age.toString()), ), DataCell( IconButton( onPressed: () { _updateTextControllers(user); }, icon: const Icon( Icons.edit, color: Colors.black, ), ), ), DataCell( IconButton( onPressed: () => _deleteTextControllers(user), icon: const Icon( Icons.delete, color: Colors.black, ), ), ), ], ), ) .toList(), ); return Scaffold( appBar: AppBar( title: const Text("通过表单添加数据到列表表格"), ), body: Container( child: Column( children: <Widget>[ bodyData(), Padding( padding: const EdgeInsets.all(10.0), child: Form( key: form, child: Container( child: Column( children: <Widget>[ TextFormField( controller: nameController, focusNode: _focusNode, keyboardType: TextInputType.text, autocorrect: false, onSaved: (value) { user.name = value!; }, maxLines: 1, validator: (value) { if (value!.isEmpty) { return '此字段为必填项'; } return null; }, decoration: const InputDecoration( labelText: '姓名', hintText: '姓名', labelStyle: TextStyle( decorationStyle: TextDecorationStyle.solid), ), ), const SizedBox( height: 10, ), TextFormField( controller: ageController, keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], autocorrect: false, maxLines: 1, validator: (value) { if (value!.isEmpty) { return '此字段为必填项'; } if (int.tryParse(value) == null) { return '请输入有效的整数年龄'; } return null; }, onSaved: (value) { user.age = int.parse(value!); }, decoration: const InputDecoration( labelText: '年龄', hintText: '年龄', labelStyle: TextStyle( decorationStyle: TextDecorationStyle.solid)), ), const SizedBox( height: 10, ), Column( children: <Widget>[ Center( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextButton( child: const Text("添加"), onPressed: () { if (validate() == true) { form.currentState?.save(); addUserToList( user.name, user.age, ); clearForm(); } }, ), TextButton( child: const Text("更新"), onPressed: () { if (validate() == true) { form.currentState?.save(); updateForm(user); clearForm(); } }, ), ], ), ), ], ), ], ), ), ), ), ], ), ), ); } void updateForm(User user) { setState(() { User updatedUser = User( name: nameController.text, age: int.parse(ageController.text), ); userList[currentIndex] = updatedUser; }); } void _updateTextControllers(User user) { setState(() { nameController.text = user.name; ageController.text = user.age.toString(); }); } void _deleteTextControllers(User user) { setState(() { int currentIndex = userList.indexOf(user); userList.removeAt(currentIndex); }); } void addUserToList(String name, int age) { setState(() { userList.add(User(name: name, age: age)); }); } void clearForm() { nameController.clear(); ageController.clear(); } bool validate() { var valid = form.currentState!.validate(); if (valid) form.currentState!.save(); return valid; } }
关键改动说明
- 移除冗余的字符串类型年龄字段,统一用整数类型存储,避免类型转换混乱
- 通过输入过滤器从源头限制非数字输入,配合表单验证提前拦截无效值
- 所有数据操作逻辑统一使用整数类型年龄,确保数据类型一致性
内容的提问来源于stack exchange,提问作者Q40
相关产品推荐
相关产品推荐

