Flutter中选择Dropdown或日期后所有表单字段被重置问题如何解决?
问题根因
- 你将所有表单状态变量(文本输入控制器
taskTitle/taskNotes、选中优先级selectedPriority、选中截止日期_dueDate)全部定义在build方法内部 - 每次选择优先级/日期时,Flutter会触发组件重绘执行
build方法,所有变量会被重新初始化赋值为默认值,就会出现内容被清空、选项恢复默认的问题 - 下拉选择和日期选择的
onChanged回调中没有调用setState更新状态,即使变量移出build方法,选中的值也无法同步更新到视图上
修复步骤
- 将所有状态变量从
build方法中移出,改为State类的成员属性 - 在
initState中初始化状态默认值,在dispose中销毁文本控制器避免内存泄漏 - 在下拉和日期选择的
onChanged回调中调用setState更新状态 - 将日期选择器的初始值绑定到状态变量
_dueDate,避免重绘时重置为当前日期
修复后完整代码
import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:ssms_new/Models/ToDoModel.dart'; import 'package:http/http.dart' as http; import 'package:date_time_picker/date_time_picker.dart'; import 'package:ssms_new/Tasks/AllTasksTabsView.dart'; import '../Configurations/configurations.dart'; class AddTaskModalSheet extends StatefulWidget { const AddTaskModalSheet({Key? key}) : super(key: key); @override _AddTaskModalSheetState createState() => _AddTaskModalSheetState(); } class _AddTaskModalSheetState extends State<AddTaskModalSheet> { final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); // 状态变量移到类成员位置 final TextEditingController taskTitle = TextEditingController(); final TextEditingController taskNotes = TextEditingController(); late String selectedPriority; late String _dueDate; @override void initState() { super.initState(); // 初始化默认值 selectedPriority = "Normal"; _dueDate = DateTime.now().toString(); } @override void dispose() { // 销毁控制器避免内存泄漏 taskTitle.dispose(); taskNotes.dispose(); super.dispose(); } Future<ToDoModel?> postNewTask() async { var response; String encodedPath = "task/new/$savedUserID"; if (devMode == "development") { response = await http.post(Uri.parse('$devUrl$encodedPath'), body: { "name": taskTitle.text, "note": taskNotes.text, "title": taskTitle.text, "done": "0", "priority": "$selectedPriority", "due_date": "$_dueDate", "TaskOwner": "$savedUserID", "img": "NA", "studentId": "$savedUserID", "assignerId": "0", "closeTaskNotes": "NA", }); } else { print(selectedPriority); response = await http.post(Uri.parse('$prodUrl$encodedPath'), body: { "name": taskTitle.text, "note": taskNotes.text, "title": taskTitle.text, "done": "0", "priority": "$selectedPriority", "due_date": "$_dueDate", "TaskOwner": "$savedUserID", "img": "NA", "studentId": "$savedUserID", "assignerId": "0", "closeTaskNotes": "NA", }); } print(response.statusCode); String responseString = response.body; toDoFromJson(responseString); print(response.body); return null; } @override Widget build(BuildContext context) { var screenHeight = MediaQuery.of(context).size.height; var screenWidth = MediaQuery.of(context).size.width; return Scaffold( body: SafeArea( child: SingleChildScrollView( child: Form( key: _formKey, child: Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom), color: Color(0xff737373), child: Container( decoration: BoxDecoration( color: Colors.white, ), child: Column(children: [ SizedBox(height: 20), Text( "Add New Task", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), SizedBox(height: 20), Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ TextField( controller: taskTitle, decoration: InputDecoration( labelText: "Task Title", border: OutlineInputBorder(), ), ), SizedBox(height: 10), TextField( controller: taskNotes, maxLines: 3, decoration: InputDecoration( labelText: "Task Notes", border: OutlineInputBorder(), ), ), ], ), ), SizedBox(height: 2), Container( padding: EdgeInsets.only(left: 4, right: 3), width: screenWidth / 1.05, decoration: BoxDecoration( border: Border.all(color: Colors.grey, width: 2), borderRadius: BorderRadius.circular(5)), child: DropdownButtonFormField( items: priorityList.map((String category) { return DropdownMenuItem( value: category, child: Row( children: <Widget>[ Text(category), ], )); }).toList(), onTap: () => FocusManager.instance.primaryFocus!.unfocus(), onChanged: (newValue) { // 调用setState更新状态 setState(() { selectedPriority = newValue.toString(); }); }, value: selectedPriority, ), ), DateTimePicker( type: DateTimePickerType.date, dateMask: 'd MMM, yyyy', // 初始值绑定状态变量 initialValue: _dueDate, firstDate: DateTime.now(), lastDate: DateTime(2100), icon: Icon(Icons.event), dateLabelText: 'Date', onChanged: (val) { // 调用setState更新状态 setState(() { _dueDate = val!; }); }, onSaved: (val) { _dueDate = val!; }, ), //Select Work Date SizedBox(height: 10), ElevatedButton( style: ElevatedButton.styleFrom(primary: Color(0xffe9c46a)), onPressed: () { postNewTask(); Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) { return AllTasksTabView(id: savedUserID); }), (route) => true); }, //TODO: add task here child: Text("Add Task", style: TextStyle(color: Colors.black))), SizedBox(height: 30), ]), ), ), ), ), ), ); } }
内容的提问来源于stack exchange,提问作者Mayur Khullar
相关产品推荐
相关产品推荐

