RangeError(索引):无效值:有效值范围为空:1

时间:2020-06-03 21:07:02

标签: flutter dart

整天尝试自己解决这个问题后,我不得不来寻求帮助。

我正在尝试构建此ListView.builder,它具有固定数量的itemCount。并使用从本地存储的JSON文件检索的数据构建其Widget。

我正在使用Provider传递数据。问题是,在应用启动或热重启时,ListView.builder变成红色并显示错误,然后在四分之一秒后显示我的数据。

我理解为什么会这样,我从json获取的数据列表最初是空的。因此,我将三元运算符设为:provider.data == null ? CircularProgressIndicator() : ListView.builder...,但这并不能阻止其崩溃。

我不知道为什么,这让我发疯。这是完整的代码:

我们在这里谈论的是一个称为RecommendationCardList的小部件,它通过使用随机数(在列表长度范围内)作为索引来显示上述列表中的小部件。

我在HomeScreen上有一个类似的ListView,名为CategoryCardList,其工作方式与RecommendationCardCardList类似,但是我没有遇到这个问题。另外,主屏幕的其余部分也显示良好,只有RecommendedCardList的部分在短时间内变成红色。

主屏幕课程:

    class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get user's screen properties
    // We are using this properties to adjust size accordingly
    // In order to achieve maximum responsivnes for different screen sizes
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;

    var repoProvider = Provider.of<Repository>(context);
    var recipeDataList = repoProvider.recipeDataList;

    return Container(
      color: backgroundColor,
      child: repoProvider.recipeDataList == null
          ? Center(child: CircularProgressIndicator())
          : Padding(
              padding: contentPadding,
              child: ListView(
                children: <Widget>[
                  AppTitle(),
                  SizedBox(
                    height: height * 0.03,
                  ),
                  Column(
                    children: <Widget>[
                      CategoryAndSeeAll(),
                      CategoryCardsList(height: height, provider: repoProvider),
                    ],
                  ),
                  SizedBox(
                    height: height * 0.05,
                  ),
                  Container(
                    width: double.infinity,
                    height: height * 0.1,
                    decoration: BoxDecoration(
                      border: Border.all(color: accentColor),
                    ),
                    child: Text(
                      'Reserved for AD',
                      textAlign: TextAlign.center,
                    ),
                  ),
                  SizedBox(
                    height: height * 0.05,
                  ),
                RecommendedCardsList(height: height, width: width, recipeDataList: recipeDataList),
                ],
              ),
            ),
    );
     }



       }

RecommendedCardsList类:

class RecommendedCardsList extends StatelessWidget {
  const RecommendedCardsList({
    Key key,
    @required this.height,
    @required this.width,
    @required this.recipeDataList,
  }) : super(key: key);

  final double height;
  final double width;
  final recipeDataList;
  @override
  Widget build(BuildContext context) {

    return Container(
            height: height * 0.30,
            child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: numberOfRecommendedRecipes,
                itemBuilder: (context, counter) {
                  int randomNumber = Random().nextInt(recipeDataList.length);
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                     RecommendedCard(
                        width: width,
                        height: height,
                        imagePath: recipeDataList.elementAt(randomNumber).image,
                        text: recipeDataList.elementAt(randomNumber).title,
                      ),
                    ],
                  );

                }),





          );
  }
}

存储库类:

class Repository extends ChangeNotifier {
  Repository() {
    loadJson();
  }

  var _recipeData;


  List<RecipeModel> _recipeDataList = [];
  List<RecipeModel> get recipeDataList => _recipeDataList;

  void loadJson() async {

    var json = await rootBundle.loadString('assets/recipes.json');
    var parsedJson = jsonDecode(json);
    for (var item in parsedJson) {
      _recipeData = RecipeModel.fromJson(item);
      _recipeDataList.add(_recipeData);
    }
    //print('Title:${_recipeDataList[0].title}\nImage:${_recipeDataList[0].image}'); // For debugging

    notifyListeners();
  }
}

2 个答案:

答案 0 :(得分:1)

build()小部件的RecommendedCardsList中将以下条件作为第一行。

if(recipeDataList == null || recipeDataList.length == 0){
  return Container();
}

答案 1 :(得分:0)

此错误与以下事实有关:代码在列表中搜索了索引,并且此索引大于列表长度。

我认为错误在于该部分:

int randomNumber = Random().nextInt(recipeDataList.length);

假设长度为10,则随机函数将检索0到10之间的数字,但最后一个索引为9。

考虑到这一点,我有两个建议:

1)

// changing ternary logic
(repoProvider.recipeDataList == null && repoProvider.recipeDataList.length > 0)

2)

// inside ListView.Builder change to get the list length
itemCount: recipeDataList.length