如何解决Flutter dropdownButtonFormField动态选择检查dropdownButton的值 [英] How to resolve flutter dropdownButtonFormField dynamic selection checking for dropdownButton's value

查看:76
本文介绍了如何解决Flutter dropdownButtonFormField动态选择检查dropdownButton的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让用户在第一个下拉菜单中选择项目的类型,然后在第二个下拉菜单中从其相应的可用颜色中进行选择.但是,当我选择一种颜色(即白色)并且现在想要切换到另一种不具有该颜色的项目时,会引发错误:

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. However, when after I have selected a colour (i.e. 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"

请帮助,我已经尝试在各个位置设置setState来更新值,但是仍然会发生此错误.

Please help, I have already tried to setState at various places to update the values but this error still occurs.

以下是我的代码段:

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;
        });
    },
    ),

推荐答案

这也许为时已晚,但是您可以创建一个 Map< String,List< String>> ,其中键是项目的第一个下拉列表中的值,该值将成为第二个下拉列表中的项目.

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.

在这里,我创建了一个状态,该状态存储了第一个下拉列表中的所选项目.然后,我用它来映射第二个下拉列表中的项目.

Here, I created a state that stores the selected item of the first dropdown list. Then I used it to map the items of the second dropdown list.

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,
      );
}

这篇关于如何解决Flutter dropdownButtonFormField动态选择检查dropdownButton的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆