【问题标题】:RangeError (index): Invalid value: Valid value range is empty: 0RangeError(索引):无效值:有效值范围为空:0
【发布时间】:2019-07-25 10:55:16
【问题描述】:

我正在尝试从 API 中获取一个列表,该列表是两个方法 fetchImages 和 fetchCategories。第一次显示红屏错误,然后在 2 秒后自动加载列表。您能否告诉我我的代码有什么问题以及如何避免在我的应用中显示红屏错误?

Widget build(context) {
    try{
      if (isFirst == true) {
        fetchImage();
        fetchCategories(context);
        isFirst = false;
      }
    }catch(Exception){

    }

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Lets see images!'),
        ),
        body: new Column(
          children: <Widget>[
            new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new InkResponse(
                    child: new Column(
                      children: <Widget>[
                        Padding(
                          padding: EdgeInsets.all(10.0),
                          child: new Image.asset(
                            catimages[0],
                            width: 60.0,
                            height: 60.0,
                          ),
                        ),
                        new Text(
                          categoriesText[0],
                          style: TextStyle(color: Colors.white),
                        ),
                      ],
                    ),
                    onTap: () {
                      debugPrint("on tv clikced");
                      widget.fetchApI.fetchSubCategories(context, 6);
                    }),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages[1],
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                        categoriesText[1],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on moview clicked");
                    widget. fetchApI.fetchSubCategories(context, 7);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(
                          catimages[2],
                          width: 60.0,
                          height: 60.0,
                        ),
                      ),
                      new Text(
                       categoriesText[2],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint("on news clicked");
                    widget.fetchApI.fetchSubCategories(context, 10);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset(catimages[3],
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        categoriesText[3],
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on shows clicked');
                    widget.fetchApI.fetchSubCategories(context, 8);
                  },
                ),
                new InkResponse(
                  child: new Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(10.0),
                        child: new Image.asset('assets/live_icon.png',
                            width: 60.0, height: 60.0),
                      ),
                      new Text(
                        'Live',
                        style: TextStyle(color: Colors.white),
                      ),
                    ],
                  ),
                  onTap: () {
                    debugPrint('on live clicked');
                  },
                ),
              ],
            ),
            ImageList(images,widget.fetchApI),
          ],
        ),
      ),
    );
  }

【问题讨论】:

  • "first time it is showing redscreen error" - 没有人知道“红屏错误”到底是什么 - 如果你有任何异常发布完整的堆栈跟踪
  • RangeError (index): Invalid value: Valid value range is empty: 0, 这是移动端显示的异常
  • 它还说明了它发生的位置:源文件名、行号和该行中的位置,那么这些值是什么?
  • 听起来好像需要 2 秒来加载数据,但您正在尝试立即显示它 - 对于异步进程,您总是需要等到它完成
  • @pskink,当我尝试显示文本 categoriesText[0] 时出现错误

标签: list flutter dart range


【解决方案1】:

确保指定数据列表的长度。例如,如果您使用ListView.builder,则为属性itemCount 赋予适当的值。

ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (ctx, index) {
              return WidgetItem();
            });

【讨论】:

  • 当我尝试这个时,它显示以下错误,The following NoSuchMethodError was thrown building StreamBuilder&lt;List&lt;OrderModel&gt;&gt;(dirty, state: _StreamBuilderBaseState&lt;List&lt;OrderModel&gt;, AsyncSnapshot&lt;List&lt;OrderModel&gt;&gt;&gt;#155e0): The getter 'length' was called on null. Receiver: null Tried calling: length
  • 这个简单的解决方案是我解决它所需的全部。但我很好奇为什么 Builder 不能自己解决大小问题。也许这可能是因为要列出的数据并不总是出现在某个基本节点上,而是深深嵌套在其他节点中。
  • 人们不应该投票赞成这个答案,因为 OP 没有使用构建器
【解决方案2】:

问题可能是您正在尝试访问尚未准备好的变量/数组(可能是因为未来/api 调用尚未完成)

一种快速的解决方法是检查数组的长度或检查是否为空,例如:

Text( (myArray?.length > 0 ? myArray[0] : '') );

【讨论】:

    【解决方案3】:

    有快速而肮脏的答案,和正确的答案

    又快又脏

    使用list?.elementAt(&lt;index&gt;) ?? "" 安全访问列表元素

    Widget build(context) {
        try{
          if (isFirst == true) {
            fetchImage();
            fetchCategories(context);
            isFirst = false;
          }
        }catch(Exception){
    
        }
    
        return MaterialApp(
          home: Scaffold(
            backgroundColor: Colors.black,
            appBar: AppBar(
              title: Text('Lets see images!'),
            ),
            body: new Column(
              children: <Widget>[
                new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new InkResponse(
                        child: new Column(
                          children: <Widget>[
                            Padding(
                              padding: EdgeInsets.all(10.0),
                              child: new Image.asset(
                                catimages?.elementAt(0) ?? "",
                                width: 60.0,
                                height: 60.0,
                              ),
                            ),
                            new Text(
                              categoriesText?.elementAt(0) ?? "",
                              style: TextStyle(color: Colors.white),
                            ),
                          ],
                        ),
                        onTap: () {
                          debugPrint("on tv clikced");
                          widget.fetchApI.fetchSubCategories(context, 6);
                        }),
                    new InkResponse(
                      child: new Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.all(10.0),
                            child: new Image.asset(
                              catimages?.elementAt(1) ?? "",
                              width: 60.0,
                              height: 60.0,
                            ),
                          ),
                          new Text(
                            categoriesText?.elementAt(1) ?? "",
                            style: TextStyle(color: Colors.white),
                          ),
                        ],
                      ),
                      onTap: () {
                        debugPrint("on moview clicked");
                        widget. fetchApI.fetchSubCategories(context, 7);
                      },
                    ),
                    new InkResponse(
                      child: new Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.all(10.0),
                            child: new Image.asset(
                              catimages?.elementAt(2) ?? "",
                              width: 60.0,
                              height: 60.0,
                            ),
                          ),
                          new Text(
                           categoriesText?.elementAt(2) ?? "",
                            style: TextStyle(color: Colors.white),
                          ),
                        ],
                      ),
                      onTap: () {
                        debugPrint("on news clicked");
                        widget.fetchApI.fetchSubCategories(context, 10);
                      },
                    ),
                    new InkResponse(
                      child: new Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.all(10.0),
                            child: new Image.asset(catimages?.elementAt(3) ?? "",
                                width: 60.0, height: 60.0),
                          ),
                          new Text(
                            categoriesText?.elementAt(3) ?? "",
                            style: TextStyle(color: Colors.white),
                          ),
                        ],
                      ),
                      onTap: () {
                        debugPrint('on shows clicked');
                        widget.fetchApI.fetchSubCategories(context, 8);
                      },
                    ),
                    new InkResponse(
                      child: new Column(
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.all(10.0),
                            child: new Image.asset('assets/live_icon.png',
                                width: 60.0, height: 60.0),
                          ),
                          new Text(
                            'Live',
                            style: TextStyle(color: Colors.white),
                          ),
                        ],
                      ),
                      onTap: () {
                        debugPrint('on live clicked');
                      },
                    ),
                  ],
                ),
                ImageList(images,widget.fetchApI),
              ],
            ),
          ),
        );
      }
    }
    

    正确答案

    坦率地说,如果我要查看此代码,即使它可以无缝运行,我也会拒绝此更改,因为此代码使用的结构/模式非常糟糕。

    请改用FutureBuilderStreamBuilderValueListenableBuilder,但您需要提供更多代码(尤其是fetchImagefetchCategories)以便我们提供帮助。

    【讨论】:

      【解决方案4】:

      空安全

      错误原因:

      在检索List 中不存在的索引的值时会发生此错误。例如:

      List<int> list = [];
      list[0]; // <-- Error since there's no element at index 0 in the list. 
      

      解决方案:

      检查List 是否不是null 并且在索引处有元素:

      var myList = nullableList;
      var index = 0;
      if (myList != null && myList.length > index) {
        myList[index]; // You can safely access the element here. 
      }
      

      【讨论】:

        【解决方案5】:

        你没有得到数据。缺少来自或数据源的数据文件夹。同样的事情发生在我身上。后来,我为数据创建了 json 文件并指向了那个位置。而且很简单!

        【讨论】:

          【解决方案6】:

          我假设您从 fetch ApI 方法中获取数据,如果您在 fetchApI 方法中获取数据。那么你应该遵循这个

          fetchApI 是 asynchronous 方法,因此从 json 获取数据需要时间,并且在请求中 fetchApI 为空,因此它给出了范围错误。 您可以使用 awaitasync* 创建 fetchApI 方法 asynchronous,并在调用该方法时使用 .then 方法,然后访问值。

          fetchApI().then((){ // access fetchApI over here });
          

          【讨论】:

            【解决方案7】:

            如果其他方法不起作用,请检查您的数据库是否包含任何冲突的数据条目。如果是这样,请修复它们。

            【讨论】:

              【解决方案8】:

              当我尝试访问一个空的数组时遇到了同样的问题。这是 null 安全性的一部分。

              我之前的代码是

              TextBox(response.customerDetails!.address![0].city),
              

              这导致我出错,所以我将代码更改为

              Text(
                   (response.cutomerDetails.address.isNotEmpty) 
                      ? response.customerDetails!.address![0].city 
                      : "N/A",
              ),
              

              在访问数组时添加检查。这帮助我消除了错误。

              【讨论】:

                【解决方案9】:

                如果您从 API 获取数据,请考虑使用 FutureBuilder

                【讨论】:

                  【解决方案10】:

                  对我来说,进入项目目录并运行命令flutter clean 修复了错误

                  【讨论】:

                    猜你喜欢
                    • 2021-06-16
                    • 2021-10-06
                    • 2021-11-13
                    • 2020-10-07
                    • 2021-01-01
                    • 2020-06-06
                    • 1970-01-01
                    • 2019-12-01
                    • 2021-07-31
                    相关资源
                    最近更新 更多