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

Flutter中选择Dropdown或日期后所有表单字段被重置问题如何解决?

问题根因
  • 你将所有表单状态变量(文本输入控制器taskTitle/taskNotes、选中优先级selectedPriority、选中截止日期_dueDate)全部定义在build方法内部
  • 每次选择优先级/日期时,Flutter会触发组件重绘执行build方法,所有变量会被重新初始化赋值为默认值,就会出现内容被清空、选项恢复默认的问题
  • 下拉选择和日期选择的onChanged回调中没有调用setState更新状态,即使变量移出build方法,选中的值也无法同步更新到视图上
修复步骤
  1. 将所有状态变量从build方法中移出,改为State类的成员属性
  2. 在initState中初始化状态默认值,在dispose中销毁文本控制器避免内存泄漏
  3. 在下拉和日期选择的onChanged回调中调用setState更新状态
  4. 将日期选择器的初始值绑定到状态变量_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:42:01