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

Flutter获取TextField与DropdownButton值并POST提交表单到API

Flutter 多类型表单字段收集与API提交实现

你可以按照以下步骤完成需求:

  • 第一步:初始化状态管理对象
    首先在对应页面的State类中,声明表单全局Key、文本输入控制器、下拉选中值存储变量,用于统一管理所有表单状态:
// 表单全局Key,用于触发表单校验、管理表单状态
final _formKey = GlobalKey<FormState>();

// 所有文本输入框对应的控制器,用于直接获取输入内容
final TextEditingController titleController = TextEditingController();
final TextEditingController companyController = TextEditingController();
final TextEditingController locationController = TextEditingController();
final TextEditingController descController = TextEditingController();
final TextEditingController salaryController = TextEditingController();

// 存储两个下拉组件的选中值
String? selectedCommonDropdown; // 对应普通DropdownButton的选中值
String? selectedCategory; // 对应DropdownSearch的选中分类值
  • 第二步:补全原有表单组件的缺失参数
    1. 给Form组件绑定上面声明的_formKey:Form(key: _formKey)
    2. 给原来没有绑定控制器的Location、Description、Salary三个TextFormField补上controller参数,分别绑定对应的locationController、descController、salaryController
    3. 修改两个下拉组件的onChanged回调,选中时同步更新状态变量:
// 普通DropdownButton的onChanged逻辑
onChanged: (String? val) {
  setState(() {
    selectedCommonDropdown = val;
  });
},

// DropdownSearch组件补全onChanged和selectedItem参数
DropdownSearch<String>(
  mode: Mode.MENU,
  showSearchBox: false,
  showClearButton: true,
  items: const ["Aviation", "Arts", "Business"],
  // 选中值回显
  selectedItem: selectedCategory,
  dropdownSearchDecoration: const InputDecoration(
    labelText: "Category",
    hintText: "Select Job Category",
  ),
  // 选中时更新状态
  onChanged: (String? val) {
    setState(() {
      selectedCategory = val;
    });
  },
),
  • 第三步:实现Add按钮的提交逻辑
    在按钮的onPressed回调中,按顺序完成表单校验、字段收集、接口提交操作:
onPressed: () async {
  // 触发表单校验,校验不通过直接终止流程
  if (_formKey.currentState?.validate() != true) return;

  // 校验下拉选项是否已选择,可根据业务需求调整提示
  if (selectedCommonDropdown == null || selectedCategory == null) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text("请完成所有下拉选项选择")),
    );
    return;
  }

  // 收集所有字段值,按照API要求的参数名组装提交数据
  final Map<String, dynamic> submitData = {
    "job_title": titleController.text.trim(),
    "company": companyController.text.trim(),
    "type": selectedCommonDropdown, // 替换为接口实际要求的参数名
    "category": selectedCategory,
    "location": locationController.text.trim(),
    "description": descController.text.trim(),
    "salary": salaryController.text.trim(),
  };

  // 调用接口提交数据,替换为你项目实际的网络请求逻辑
  try {
    // 示例:替换为你的接口请求代码
    // await dio.post("/job/add", data: submitData);
    
    // 提交成功后的逻辑:提示、清空表单、跳转等
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text("职位添加成功")),
    );
    // 可选:提交成功后重置表单
    _formKey.currentState?.reset();
    for (final controller in [titleController, companyController, locationController, descController, salaryController]) {
      controller.clear();
    }
    setState(() {
      selectedCommonDropdown = null;
      selectedCategory = null;
    });
  } catch (e) {
    // 提交失败的错误提示
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text("提交失败:${e.toString()}")),
    );
  }
},
  • 第四步:补充内存泄漏处理和校验规则
    1. 在页面的dispose生命周期中释放所有TextEditingController,避免内存泄漏:
@override
void dispose() {
  titleController.dispose();
  companyController.dispose();
  locationController.dispose();
  descController.dispose();
  salaryController.dispose();
  super.dispose();
}
  1. 如果需要给文本输入框加必填校验,给TextFormField添加validator属性即可,示例:
TextFormField(
  controller: titleController,
  decoration: const InputDecoration(hintText: 'Job Title'),
  validator: (value) {
    if (value?.trim().isEmpty == true) {
      return "请输入职位名称";
    }
    return null;
  },
),

注意:组装submitData的时候,Map的key需要和后端API文档要求的参数名完全一致,否则会提交失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:57:25