如何使用 DropdownButton 而不在 flutter 中设置初始选择?

问题描述 投票:0回答:3

嗨,我是 Flutter 新手。

我在使用

There should be exactly one item with [DropdownButton]'s value: .
类时遇到了异常
DropdownButton
。通过参考这个Q&A设置初始选择就解决了一次。

但我不想设置初始值。有没有办法不设置但也不例外?

谢谢,

附注 我有两个类和一个常量来显示下拉按钮。这是用于创建 DropdownMenuItems 的列表的常量:

List<String> prefectures = const [
  '北海道',
  '青森県',
  '岩手県',
  '宮城県',
  '秋田県',
  '山形県',
  '福島県',
  '茨城県',
  '栃木県',
  '群馬県',
...

这是扩展的类

DropdownButton

class MyDropdownButton extends StatelessWidget {
  final String                 value;
  final void Function(String?) onChanged;
  final List<String>           options;
  final String?                hintText;
  const MyDropdownButton(
    {required this.value, required this.onChanged, required this.options, this.hintText, super.key}
  );

  List<DropdownMenuItem<String>> createOptions() {
    return options.toSet().map<DropdownMenuItem<String>>(
      (option) => DropdownMenuItem(value : option, child : Text(option))
    ).toList();
  }

  @override
  Widget build(BuildContext context) {
    return DropdownButtonHideUnderline(
      child : DropdownButton(
        elevation : 3,
        items     : createOptions(),
        onChanged : onChanged,
        style     : const TextStyle(
          color    : Colors.black,
          fontSize : 15
       ),
        value     : value
      )
    );
  }
}

这就是我使用上面的类的地方:

MyDropdownButton(
  // They are also passed from other class.
  value     : widget.prefectureValue,     // this has null value
  onChanged : widget.onChangedPrefecture, // (String? newValue) => setState(() => _prefectureValue = newValue);
  options   : prefectures
)
flutter
3个回答
0
投票

应该只有一个项目具有 [DropdownButton] 的值: 意味着您有多个 DropdownMenuItem 具有相同的值。您可以将数据列表转换为 Set,大多数时候它都有效。

这里的物品是

 List<String> items = [...];
 String? selectedItem;

还有下拉按钮

DropdownButton<String?>(
  items: items
      .toSet()
      .map(
        (e) => DropdownMenuItem<String?>(
          value: e,
          child: Text(e),
        ),
      )
      .toList(),
  onChanged: (value) {},
)

固定型号

class MyDropdownButton extends StatelessWidget {
  final String? value;
  final void Function(String?) onChanged;
  final List<String> options;
  final String? hintText;
  const MyDropdownButton(
      {required this.value,
      required this.onChanged,
      required this.options,
      this.hintText,
      super.key});

  List<DropdownMenuItem<String>> createOptions() {
    return options
        .toSet()
        .map<DropdownMenuItem<String>>(
            (option) => DropdownMenuItem(value: option, child: Text(option)))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return DropdownButtonHideUnderline(
        child: DropdownButton(
            elevation: 3,
            items: createOptions(),
            onChanged: onChanged,
            style: const TextStyle(
              color: Colors.black,
              fontSize: 15,
            ),
            value: value));
  }
}

这是我的使用方法

List<String> prefectures = const [
    '北海道',
    '青森県',
    '岩手県',
    '宮城県',
    '秋田県',
    '山形県',
    '福島県',
    '茨城県',
    '栃木県',
    '群馬県',
  ];

  late String? value = prefectures.first;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          MyDropdownButton(
            value: value, //null,
            onChanged: (v) {
              setState(() {
                value = v;
              });
            }, 
            options: prefectures,
          ),

0
投票

解决方案很简单,只要您使用的是最新版本的 flutter 3.5 或更高版本,请将initialValue 保留为 null

var _selectedItem;
  Widget buildDropdownButton() {
    return DropdownButton(
      hint: const Text('Select Item'),
      value: _selectedItem,
      onChanged: (value) {
        setState(() {
          _selectedItem = value;
        });
      },
      items: ["Item 1", "Item 2", "Item 3", "Item 4"]
          .map((e) => DropdownMenuItem(
                value: e,
                child: Text(e),
              ))
          .toList(),
    );
  }

输出将如下所示


0
投票

@tk_tanz 的解决方案是正确且简单的。!

© www.soinside.com 2019 - 2024. All rights reserved.