首页 > 解决方案 > Flutter DropdownButton 错误“RangeError (index): Invalid value: Not in range 0..10, inclusive: 11”

问题描述

我有一个用于插入项目的页面,其中一个 DropdownButton 包含可供选择的类别列表。然后旁边有一个按钮,您可以使用它在下拉项目中添加新类别,而无需重新加载页面“下图”

旁边有 IconButton 的下拉菜单

当我添加新类别时遇到以下错误的问题:“RangeError (index): Invalid value: Not in range 0..10, inclusive: 11”。

该错误会在 UI“这个红色错误框”中显示几秒钟,然后消失。我的猜测是它的发生是因为 DropdownButton 中的项目数在重建发生之前发生了变化。

我搜索了这样的东西,但我找不到任何解决方案,而且没有像“listView Builder”这样的 DropdownButton 的“计数”属性来帮助我,所有可用的解决方案都适用于 listView,与 DropdownButton 无关。

dorpdown 中的代码:

class AndroidDropdown extends StatefulWidget {
  final List dropDownData;
  final Function getSelectedValue;
  //valueFromDB: used for the edit case, when there is already saved value
  final int valueFromDB;

  AndroidDropdown(
      {@required this.dropDownData,
      @required this.getSelectedValue,
      this.valueFromDB});

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

class _AndroidDropdownState extends State<AndroidDropdown> {
  String _selectedValue;
  int prevValueFromDB;

  @override
  void initState() {
    super.initState();
    //check if there a data from the DB (for update reasons)
    if (widget.valueFromDB != null) {
      int listIndex = widget.valueFromDB - 1;
      _selectedValue = widget.dropDownData[listIndex];
      widget.getSelectedValue(widget.valueFromDB);
      prevValueFromDB = widget.valueFromDB; //to use in checkIfNewValueAdded()
    } else {
      //make the default selected is the first value
      _selectedValue = widget.dropDownData[0];
      //assign a default value for the function in case the user didn't use onChange
      widget.getSelectedValue(1);
    }
  }

  @override
  Widget build(BuildContext context) {
    checkIfNewValueAdded();
    List<DropdownMenuItem<dynamic>> dropdownItems = [];
    //the items loop function
    for (var item in widget.dropDownData) {
      var newItem = DropdownMenuItem(
        child: Text(item),
        value: item,
      );
      dropdownItems.add(newItem);
    }

    return DropdownButton<dynamic>(
      value: _selectedValue, //for initial value
      items: dropdownItems,
      onChanged: (value) {
        setState(() {
          _selectedValue = value;
          widget.getSelectedValue(widget.dropDownData.indexOf(value) + 1);
          //I used this trick to get the ID of the item type that saved in the DB
        });
      },
    );
  }

  //this to check if there is a new value added in the list
  void checkIfNewValueAdded() {
    if (widget.valueFromDB != prevValueFromDB) {
      setState(() {
        int listIndex = widget.valueFromDB - 1;
        _selectedValue = widget.dropDownData[listIndex];
        prevValueFromDB = widget.valueFromDB;
      });
    }
  }
}

标签: flutterdropdownbutton

解决方案


推荐阅读