简体   繁体   English

如何解决 flutter dropdownButtonFormField 动态选择检查 dropdownButton 的值

[英]How to resolve flutter dropdownButtonFormField dynamic selection checking for dropdownButton's value

I am trying to ask the user to select the type of item in the first dropdown and then select from its corresponding available colours in the second dropdown.我试图询问用户 select 第一个下拉列表中的项目类型,然后 select 在第二个下拉列表中相应的可用颜色。 However, when after I have selected a colour (ie white) and now want to switch to another item that does not have this colour, an error is thrown:但是,当我选择了一种颜色(即白色)后,现在想要切换到另一个没有这种颜色的项目时,会抛出一个错误:

"There should be exactly one item with [DropdownButton]'s value: white. \nEither zero or 2 or more
[DropdownMenuItem]s were detected with the same value"

Please help, I have already tried to setState at various places to update the values but this error still occurs.请帮忙,我已经尝试在不同的地方设置状态来更新值,但这个错误仍然发生。

The following is my code snippet:以下是我的代码片段:

StreamBuilder<QuerySnapshot>(
    stream: mainItemsSnapshots,
    builder: (context, snapshot) {
    if (snapshot.hasError) return Text("Error");
    switch (snapshot.connectionState) {
        case ConnectionState.waiting:
        return Center(child: CircularProgressIndicator());
        default:
        {
            List<DropdownMenuItem> dropdownMenuItems =
                snapshot.data.documents
                    .map((DocumentSnapshot mainItem) {
            return new DropdownMenuItem<String>(
                value: mainItem.documentID,
                child: Text(mainItem.documentID),
            );
            }).toList();
            return DropdownButtonFormField<String>(
            items: dropdownMenuItems,
            onChanged: (String value) {
                if (value != tempMainItemType) {
                    setState(() {
                    tempMainItemType = value;
                    tempItemColorsList.clear();
                    tempItemColorsList = [];
                    tempMainItemColor = null;
                    });
                }
                
                if (tempItemColorsList.isEmpty && value != null) {
                tempItemColorsList = snapshot.data.documents
                    .where((element) => element.documentID == value)
                    .first
                    .data["colors"]
                    .keys
                    .map((color) => color.toString())
                    .toList()
                    .cast<String>();
                }
                setState((){});
            },
            onSaved: (String value) {
                _order.mainItemType = value;
            },
            value: tempMainItemType,
            );
        }
    }
    },
),

// Main color
if (tempItemColorsList?.isNotEmpty)
    Padding(
    padding: const EdgeInsets.only(top: spacingGeneral),
    child: textFieldLabel(context, "Main color"),
    ),
if (tempItemColorsList?.isNotEmpty)
    DropdownButtonFormField(
    items: tempItemColorsList.map((String color) {
        return new DropdownMenuItem<String>(
        value: color,
        child: Text(color),
        );
    }).toList(),
    onSaved: (String value) {
        _order.mainColor = value;
    },
    value: tempMainItemColor,
    onChanged: (String value) {
        setState(() {
        tempMainItemColor = value;
        });
    },
    ),

This maybe too late, but you can create a Map<String, List<String>> where the keys are the items of the first dropdown list, and the value will be the items of second dropdown list.这可能为时已晚,但是您可以创建一个Map<String, List<String>> ,其中键是第一个下拉列表的项目,值将是第二个下拉列表的项目。

Here, I created a state that stores the selected item of the first dropdown list.在这里,我创建了一个 state 来存储第一个下拉列表的选定项。 Then I used it to map the items of the second dropdown list.然后我用它来 map 第二个下拉列表的项目。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SampleDD(),
    );
  }
}

class SampleDD extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: DoubleDropdown(
          items: <String, List<String>>{
            'dark colors': ['black', 'gray', 'brown'],
            'light colors': ['white', 'yellow', 'green'],
          },
          onChangedFirst: (val) => print('Selected first: $val'),
          onChangedSecond: (val) => print('Selected second: $val'),
        ),
      ),
    );
  }
}

class DoubleDropdown extends StatefulWidget {
  DoubleDropdown({
    @required this.items,
    @required this.onChangedFirst,
    @required this.onChangedSecond,
  });

  final Map<String, List<String>> items;
  final ValueChanged<String> onChangedFirst;
  final ValueChanged<String> onChangedSecond;

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

class _DoubleDropdownState extends State<DoubleDropdown> {
  String selectedKey;

  @override
  void initState() {
    super.initState();
    selectedKey = widget.items.keys.first;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        _buildFirstDropdown(),
        _buildSecondDowndown(),
      ],
    );
  }

  Widget _buildFirstDropdown() => DropdownButtonFormField<String>(
        items: widget.items.keys.map((e) {
          return DropdownMenuItem<String>(
            child: Text(e),
            value: e,
          );
        }).toList(),
        onChanged: (val) {
          setState(() => selectedKey = val);
          widget.onChangedFirst(val);
        },
        value: selectedKey,
      );

  Widget _buildSecondDowndown() => DropdownButtonFormField<String>(
        items: widget.items[selectedKey].map((e) {
          return DropdownMenuItem<String>(
            child: Text(e),
            value: e,
          );
        }).toList(),
        onChanged: widget.onChangedSecond,
        value: widget.items[selectedKey].first,
      );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Flutter:动态 DropDownButton 出错(一个项目具有 [DropdownButton] 的值) - Flutter : Dynamic DropDownButton get error (one item with [DropdownButton]'s value) 如何在 Flutter DropdownButtonFormField 中重置值 - How to reset value in Flutter DropdownButtonFormField Flutter 在不使用 DropDownButtonFormField 的情况下验证 DropDownButton - Flutter Validate DropDownButton without using DropDownButtonFormField Flutter - DropdownButton 值在选择后保持为空 - Flutter - DropdownButton value stays empty after selection 如何在 flutter 的 DropdownButton 中设置不同的值而不是项目的值? - How to set different value instead of items's value in DropdownButton in flutter? 如何通过单击按钮获取 DropdownButtonFormField 值 - Flutter - How to get DropdownButtonFormField value with a button click - Flutter 更改两级 DropdownButtonFormField:应该只有一项具有 [DropdownButton] 的值 - Changing Two Level DropdownButtonFormField : There should be exactly one item with [DropdownButton]'s value Flutter - DropdownButtonFormField 值未更新 - Flutter - DropdownButtonFormField value not updating 如何添加 Flutter DropdownButtonFormField - How to add Flutter DropdownButtonFormField flutter动态列表如何使用DropDownButton? - How to use DropDownButton for dynamic list in flutter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM