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

Flutter Web:如何从Dialog中的DropDownList获取返回值

如何从Flutter自定义Dialog中获取DropdownList的选中值

问题场景

开发类移动端的Flutter Web应用,自定义Dialog包含三个DropDownList(ComboBox),外观和运行正常,但无法读取DropDownList的选中值,需要点击OK按钮后根据选中值跳转页面并填充内容。

解决方案

通过子组件回调传值+父组件统一管理状态+Dialog返回结果的方式实现,步骤如下:


1. 修改DropdownButtonExample组件,添加选中值回调

给子组件添加回调函数,用于将选中值传递给父Dialog组件:

import 'package:flutter/material.dart';

class DropdownButtonExample extends StatefulWidget {
  const DropdownButtonExample({
    super.key,
    required this.listType,
    required this.onValueChanged, // 新增回调函数
  });

  final List<String> listType;
  final Function(String?) onValueChanged; // 传递选中值的回调

  @override
  State<DropdownButtonExample> createState() => _DropdownButtonExampleState();
}

class _DropdownButtonExampleState extends State<DropdownButtonExample> {
  String? dropdownValue;

  @override
  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      icon: const Icon(Icons.arrow_downward),
      elevation: 10,
      style: const TextStyle(color: Colors.blue),
      underline: Container(
        height: 2,
        color: Colors.blue,
      ),
      onChanged: (String? value) {
        setState(() {
          dropdownValue = value;
        });
        widget.onValueChanged(value); // 触发回调,传递选中值
      },
      items: widget.listType.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

2. 修改CustomDialogBox,管理选中状态并返回结果

在Dialog组件中维护三个DropDownList的选中值,点击OK时将结果返回给调用方:

class CustomDialogBox extends StatefulWidget {
  final String title, descriptions, text;

  const CustomDialogBox({
    Key? key,
    required this.title,
    required this.descriptions,
    required this.text,
  }) : super(key: key);

  @override
  _CustomDialogBoxState createState() => _CustomDialogBoxState();
}

class _CustomDialogBoxState extends State<CustomDialogBox> {
  String? selectedList1; // 存储第一个下拉框选中值
  String? selectedList2; // 存储第二个下拉框选中值
  String? selectedList3; // 存储第三个下拉框选中值

  @override
  Widget build(BuildContext context) {
    return Dialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(15),
      ),
      elevation: 0,
      backgroundColor: Colors.transparent,
      child: contentBox(context),
    );
  }

  contentBox(context) {
    return Stack(
      children: <Widget>[
        Container(
          padding:
              const EdgeInsets.only(left: 50, top: 75, right: 50, bottom: 50),
          margin: const EdgeInsets.only(top: 40),
          decoration: BoxDecoration(
            shape: BoxShape.rectangle,
            color: Colors.white,
            borderRadius: BorderRadius.circular(15),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const SizedBox(height: 80),
              Text(
                widget.title,
                style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w600),
              ),
              const SizedBox(height: 15),
              Text(
                widget.descriptions,
                style: const TextStyle(fontSize: 14),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 30),
              // 第一个下拉框,绑定回调
              DropdownButtonExample(
                listType: list1,
                onValueChanged: (value) {
                  setState(() => selectedList1 = value);
                },
              ),
              const SizedBox(height: 30),
              // 第二个下拉框,绑定回调
              DropdownButtonExample(
                listType: list2,
                onValueChanged: (value) {
                  setState(() => selectedList2 = value);
                },
              ),
              const SizedBox(height: 30),
              // 第三个下拉框,绑定回调
              DropdownButtonExample(
                listType: list3,
                onValueChanged: (value) {
                  setState(() => selectedList3 = value);
                },
              ),
              Align(
                alignment: Alignment.bottomRight,
                child: MaterialButton(
                  color: Colors.blue,
                  onPressed: () {
                    // 将三个选中值打包返回给调用方
                    Navigator.of(context).pop({
                      'list1': selectedList1,
                      'list2': selectedList2,
                      'list3': selectedList3,
                    });
                  },
                  child: Text(
                    widget.text,
                    style: const TextStyle(fontSize: 18, color: Colors.white),
                  ),
                ),
              ),
            ],
          ),
        ),
        Positioned(
          left: 30,
          right: 30,
          top: 0,
          child: CircleAvatar(
            backgroundColor: Colors.blue,
            radius: 80,
            child: ClipRRect(
              borderRadius: BorderRadius.all(Radius.circular(75)),
              child: Image.network(
                "https://images.pexels.com/photos/627678/pexels-photo-627678.jpeg?auto=compress&cs=tinysrgb&w=1600",
                width: 120,
                height: 120,
                fit: BoxFit.fill,
              ),
            ),
          ),
        ),
      ],
    );
  }
}

// 下拉框选项列表保持不变
const List<String> list1 = <String>[
  'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve'
];
const List<String> list2 = <String>[
  'Black', 'Red', 'Olive', 'DarkOliveGreen', 'MediumAquamarine', 'DarkSeaGreen', 'LightSeaGreen', 'DarkCyan', 'Teal'
];
const List<String> list3 = <String>['Slow', 'Medium', 'Fast'];

3. 在调用Dialog的页面接收结果并处理

通过await获取Dialog返回的选中值,后续执行页面跳转和内容填充逻辑:

// 示例:在main.dart中调用Dialog
ElevatedButton(
  onPressed: () async {
    // 等待Dialog返回结果
    var selectedValues = await showDialog(
      context: context,
      builder: (context) => CustomDialogBox(
        title: "选择参数",
        descriptions: "请选择三个选项",
        text: "确定",
      ),
    );

    if (selectedValues != null) {
      // 解析选中值
      String? val1 = selectedValues['list1'];
      String? val2 = selectedValues['list2'];
      String? val3 = selectedValues['list3'];

      // 根据选中值执行页面跳转和内容填充
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => TargetPage(
            value1: val1,
            value2: val2,
            value3: val3,
          ),
        ),
      );
    }
  },
  child: const Text("打开Dialog"),
)

关键说明

  • 子组件通过回调函数向父Dialog传递选中值,实现组件间通信
  • Dialog统一管理所有下拉框的状态,点击OK时将结果通过Navigator.pop()返回
  • 调用方通过await接收结果,完成后续业务逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:15:39