Flutter根据列表长度在for循环中生成多个下拉列表

时间:2020-04-06 13:40:23

标签: flutter

我有一个代码,其中有一个基于列表长度的多个下拉框。该代码运行良好,现在让我们说它正在生成带有选项的两个下拉框。问题是,无论何时我从第一个下拉列表框中选择一个选项,都会影响第二个下拉列表值,反之亦然,每当我从第二个下拉列表中选择一个选项时,都会影响第一个下拉列表值。问题是我知道我对两个下拉框的值都使用了一个变量,但是我不知道如何根据下拉框名称或任何其他产生变量的方式来生成动态变量,下拉框。我尝试使用列表变量来保存基于下拉框的值,但它也无法正常工作。所以我现在迷路了,我不知道该怎么解决。这是代码:

class DropdownAttributes extends StatefulWidget {
  final List<Attributes> attributes;
  final List<AllAttributes> allAttributes;

  const DropdownAttributes({Key key, this.attributes, this.allAttributes})
      : super(key: key);

  State createState() => DropdownAttributesState();
}

class DropdownAttributesState extends State<DropdownAttributes> {
  int selectedAttributes;

  @override
  Widget build(BuildContext context) {
    //We make an integer list first to hold all the attribute id's in the product
    List<int> attributeIds = [];

    //we push the attribute id's to the integer list "attributeIds"
    widget.attributes.map((Attributes attributes) {
      attributeIds.add(attributes.attributeId);
    }).toList();

    //we remove all the duplicates so that when we loop into it we don't duplicate the results
    List<int> removedDuplicates =
    LinkedHashSet<int>.from(attributeIds).toList();

    return Column(
        children: widget.allAttributes.map((AllAttributes allAttributes) {
          bool attributeCheck;
          //we check if removedDuplicates contains any of the id's that in the allAttributes.id
          if (removedDuplicates.contains(allAttributes.id)) {
            attributeCheck = true;
          } else {
            attributeCheck = false;
          }

          //we are in the loop, if we any attribute.attribute.id equals allAttributes.id return a dropdown with it's options
          if (attributeCheck) {
            return Row(
              children: <Widget>[
                new Container(
                    alignment: Alignment(-1.0, -1.0),
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 10.0, right: 10.0),
                      child: Text(
                        allAttributes.name + ':',
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 20,
                            fontWeight: FontWeight.w600),
                      ),
                    )),
                DropdownButton<int>(
                  hint: Text("Select a " + allAttributes.name),
                  value: allAttributes.id,
                  onChanged: (int Value) {
                    setState(() {
                      selectedAttributes = Value;
                    });
                    print(selectedAttributes);
                  },
                  items: widget.attributes.map((Attributes attributes) {
                    bool listCheck;
                    if (attributes.attributeId == allAttributes.id) {
                      listCheck = true;
                    } else {
                      listCheck = false;
                    }

                    if(listCheck){
                      return DropdownMenuItem<int>(
                        value: attributes.id,
                        child: Row(
                          children: <Widget>[
                            SizedBox(
                              width: 10,
                            ),
                            Text(
                              attributes.value,
                              style: TextStyle(color: Colors.black),
                            ),
                          ],
                        ),
                      );
                    } else{
                      return DropdownMenuItem<int>(
                        value: attributes.id,
                        child: Container(),
                      );
                    }
                  }).toList(),
                ),
              ],
            );
          } else {
            return Container();
          }
        }).toList());
  }
}

更新: 只是为了使问题更加清楚,下拉列表并不相互依赖,它们都是独立的下拉列表,但是它们是在for循环中生成的。现在在我的代码中,所有生成的下拉列表都在更改一个变量int selectedAttributes;而不是更改每个变量各自的变量。我无法弄清楚如何为每个变量生成变量,以便以后可以访问它们。我只能访问一个变量,该变量为 int selectedAttributes; ,但是它受生成的所有下拉列表的影响,我不希望这样做。

使用答案更新: 下面的代码是最终的工作代码,我只是想在以后遇到相同问题的任何人中添加它,下面的代码基于@JoãoSoares的回答,并做了一些更改以适应我的条件。

class DropdownAttributes extends StatefulWidget {
  final List<Attributes> attributes;
  final List<AllAttributes> allAttributes;

  const DropdownAttributes({Key key, this.attributes, this.allAttributes})
      : super(key: key);

  State createState() => DropdownAttributesState();
}

class DropdownAttributesState extends State<DropdownAttributes> {
  int selectedAttributes;
  List<int> dropdownValues = [];

  @override
  void initState() {
    widget.allAttributes.map((AllAttributes allAttributes) {
      dropdownValues = List.generate(
          widget.allAttributes.length, (value) => allAttributes.id);
    }).toList();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    //We make an integer list first to hold all the attribute id's in the product
    List<int> attributeIds = [];

    //we push the attribute id's to the integer list "attributeIds"
    widget.attributes.map((Attributes attributes) {
      attributeIds.add(attributes.attributeId);
    }).toList();

    //we remove all the duplicates so that when we loop into it we don't duplicate the results
    List<int> removedDuplicates =
    LinkedHashSet<int>.from(attributeIds).toList();

    return Column(
        children: widget.allAttributes.map((AllAttributes allAttributes) {
          dropdownValues.add(allAttributes.id);
          bool attributeCheck;
          //we check if removedDuplicates contains any of the id's that in the allAttributes.id
          if (removedDuplicates.contains(allAttributes.id)) {
            attributeCheck = true;
          } else {
            attributeCheck = false;
          }

          //we are in the loop, if we any attribute.attribute.id equals allAttributes.id return a dropdown with it's options
          if (attributeCheck) {
            return Row(
              children: <Widget>[
                new Container(
                    alignment: Alignment(-1.0, -1.0),
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 10.0, right: 10.0),
                      child: Text(
                        allAttributes.name + ':',
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 20,
                            fontWeight: FontWeight.w600),
                      ),
                    )),
                DropdownButton<int>(
                  hint: Text("Select a " + allAttributes.name),
                  value: dropdownValues[allAttributes.id],
                  onChanged: (value) =>
                      onDropDownChange(allAttributes.id, value),
                  items: widget.attributes.map((Attributes attributes) {
                    bool listCheck;
                    if (attributes.attributeId == allAttributes.id) {
                      listCheck = true;
                    } else {
                      listCheck = false;
                    }

                    if (listCheck) {
                      return DropdownMenuItem<int>(
                        value: attributes.id,
                        child: Row(
                          children: <Widget>[
                            SizedBox(
                              width: 10,
                            ),
                            Text(
                              attributes.value,
                              style: TextStyle(color: Colors.black),
                            ),
                          ],
                        ),
                      );
                    } else {
                      return DropdownMenuItem<int>(
                        value: attributes.id,
                        child: Container(),
                      );
                    }
                  }).toList(),
                ),
              ],
            );
          } else {
            return Container();
          }
        }).toList());
  }

  void onDropDownChange(dropDownIndex, value) {
    setState(() {
      dropdownValues[dropDownIndex] = value;
    });
    print('onDropDownChange: $dropDownIndex -> $value');
  }
}

1 个答案:

答案 0 :(得分:1)

可以使用以下示例代码来创建DropDownButton的动态生成器。但是要使DropDownButton动态知道需要更改哪些其他DropDownButton,您还必须在DropDownButton之间传递这些连接的映射。

class Attribute {
  int value;
  String name;

  Attribute({
    @required this.value,
    @required this.name
  });
}

class MultiDropDown61061194 extends StatefulWidget {
  final List<List<Attribute>> lists;

  MultiDropDown61061194({this.lists});

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

class _MultiDropDown61061194State extends State<MultiDropDown61061194> {
  List<int> dropdownValues = [];

  @override
  void initState() {
    dropdownValues = List.generate(widget.lists.length, (value) => 1);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 200,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: List.generate(widget.lists.length, (index) {
            return Container(
              child: DropdownButton(
                isExpanded: true,
                onChanged: (value) => onDropDownChange(index, value),
                value: dropdownValues[index],
                items: widget.lists[index].map((list) {
                  return DropdownMenuItem(
                    child: Text('${list.name}'),
                    value: list.value,
                  );
                }).toList(),
              ),
            );
          })
        ),
      ),
    );
  }

  void onDropDownChange(dropDownIndex, value){
    setState(() {
      dropdownValues[dropDownIndex] = value;
    });
    print('onDropDownChange: $dropDownIndex -> $value');
  }
}

通过列表调用课程:

MultiDropDown61061194(
  lists: [
    [
      Attribute(
        value: 1,
        name: 'A'
      ),
      Attribute(
        value: 2,
        name: 'B'
      ),
      Attribute(
        value: 3,
        name: 'C'
      ),
    ],
    [
      Attribute(
          value: 1,
          name: 'Alpha'
      ),
      Attribute(
          value: 2,
          name: 'Beta'
      ),
      Attribute(
          value: 3,
          name: 'Charlie'
      ),
    ],
  ],
),
相关问题