【问题标题】:Flutter Error: RangeError (index): Invalid value: Not in range 0..2, inclusive: 3颤振错误:RangeError(索引):无效值:不在0..2范围内,包括:3
【发布时间】:2019-05-26 19:34:50
【问题描述】:

我在 Flutter 中使用了很长的列表。所有项目都呈现正常,但我也收到以下错误:

RangeError (index): Invalid value: Not in range 0..2, inclusive: 3

以下是我的代码:

@override
Widget build(BuildContext context) {
return Container(
  child: getList(),
 );
}

以下是我的getList()方法:

Widget getList (){
List<String> list = getListItems();
ListView myList = new ListView.builder(itemBuilder: (context, index){
  return new ListTile(
    title: new Text(list[index]),
  );
});
return myList;
}

以下是我的getListItem()方法:

List<String> getListItems(){
return ["Faizan", "Usman", "Naouman"];
}

以下是错误截图:

【问题讨论】:

  • itemCount参数添加到ListView.builder()构造函数

标签: android flutter dart


【解决方案1】:

您应该将itemCount 参数传递给ListView.builder 以使其知道项目数

Widget getList() {
  List<String> list = getListItems();
  ListView myList = new ListView.builder(
    itemCount: list.length,
    itemBuilder: (context, index) {
    return new ListTile(
      title: new Text(list[index]),
    );
  });
  return myList;
}

【讨论】:

  • 如果我的列表没有固定长度(例如无限滚动)怎么办?
  • @RichardMcFriendOluwamuyiwa Listview.builder 用于指定长度的列表,不知道长度的可以使用listview
  • 不幸的是,它对 AnimatedList 没有帮助
  • 我正在使用 SliverList,我没有找到任何指定 itemCount 的选项:(
  • @ElhamKeshavarz 您的评论错误且具有误导性。这是listview.builder的官方说明:This constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are actually visible. Providing a non-null itemCount improves the ability of the ListView to estimate the maximum scroll extent.
【解决方案2】:
Widget getListView(){
  var itemList = getListElement();
   var list = ListView.builder(
     itemCount: itemList.length,
       itemBuilder:(context, index){
         return ListTile(
           title: Text(itemList[index]),   
         );
         }
   );
   return list;
}

【讨论】:

    【解决方案3】:

    我在 GridView 中遇到了这个问题,但它与我的 GridView 无关。我用逗号分隔地址,例如addresses[index].split(',')[0],但我遇到了一个没有逗号的地址,这就是为什么我突然收到这个错误的原因。仔细查看调试控制台以找到错误的确切行,并测试 GridView 中的每一段代码以查明错误。

    【讨论】:

    • 问题在于列表数据长度,我忘了在代码中提到data_list.length
    【解决方案4】:

    如果你使用StreamBuilder,那么你必须使用这行代码:

      StreamBuilder(
                      stream: FirebaseFirestore.instance.collection("Tooth")
                      .orderBy("date", descending: false).snapshots() ,
                    
                      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
                     
                        if(snapshot.hasData)
                        {
                          return ListView.builder(
                            itemCount: snapshot.data.docs.length,
                              padding: const EdgeInsets.only( top: 20.0),
                            itemBuilder: (BuildContext context, int index) {
                               DocumentSnapshot ds = snapshot.data.docs[index];
     },
                          );
                        }
                       
                      },
                    ),
    

    【讨论】:

      【解决方案5】:

      有限滚动

      解决方案很简单,您只需将itemCount 添加到构建器,以便构建器允许它知道项目数。就像上面的代码一样this answer

      无限滚动

      要进行无限滚动,请使用 ListView.builder 而不指定 itemCount 参数。

        body: ListView.builder(
         itemCount: _photos.length + (_hasMore ? 1 : 0),
          itemBuilder: (context, index) {
            if (index == item.length - _nextPageThreshold) {
              // Here is your manuplated data code
            } else {
              getMoreData();
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
      

      完整代码示例

      class ItemListScreen extends StatefulWidget {
        ItemListScreen({Key key}) : super(key: key);
        @override
        _PhotosListScreenState createState() => _PhotosListScreenState();
      }
      
      class _PhotosListScreenState extends State<ItemListScreen> {
        bool _hasMore;
        int _pageNumber;
        bool _error;
        bool _loading;
        final int _defaultPhotosPerPageCount = 10;
        List<Photo> _photos;
        final int _nextPageThreshold = 5;
        @override
        void initState() {
          super.initState();
          _hasMore = true;
          _pageNumber = 1;
          _error = false;
          _loading = true;
          _photos = [];
          fetchPhotos();
        }
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(title: Text("Photos App")),
            body: getBody(),
          );
        }
      
        Widget getBody() {
          if (_photos.isEmpty) {
            if (_loading) {
              return Center(
                  child: Padding(
                    padding: const EdgeInsets.all(8),
                    child: CircularProgressIndicator(),
                  ));
            } else if (_error) {
              return Center(
                  child: InkWell(
                    onTap: () {
                      setState(() {
                        _loading = true;
                        _error = false;
                        fetchPhotos();
                      });
                    },
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Text("Error while loading photos, tap to try agin"),
                    ),
                  ));
            }
          } else {
            return ListView.builder(
                itemCount: _photos.length + (_hasMore ? 1 : 0),
                itemBuilder: (context, index) {
                  if (index == _photos.length - _nextPageThreshold) {
                    fetchPhotos();
                  }
                  if (index == _photos.length) {
                    if (_error) {
                      return Center(
                          child: InkWell(
                            onTap: () {
                              setState(() {
                                _loading = true;
                                _error = false;
                                fetchPhotos();
                              });
                            },
                            child: Padding(
                              padding: const EdgeInsets.all(16),
                              child: Text("Error while loading photos, tap to try agin"),
                            ),
                          ));
                    } else {
                      return Center(
                          child: Padding(
                            padding: const EdgeInsets.all(8),
                            child: CircularProgressIndicator(),
                          ));
                    }
                  }
                  final Photo photo = _photos[index];
                  return Card(
                    child: Column(
                      children: <Widget>[
                        Image.network(
                          photo.thumbnailUrl,
                          fit: BoxFit.fitWidth,
                          width: double.infinity,
                          height: 160,
                        ),
                        Padding(
                          padding: const EdgeInsets.all(16),
                          child: Text(photo.title,
                              style: TextStyle(
                                  fontWeight: FontWeight.bold, fontSize: 16)),
                        ),
                      ],
                    ),
                  );
                });
          }
          return Container();
        }
      
        Future<void> fetchPhotos() async {
          try {
            final response = await http.get("https://jsonplaceholder.typicode.com/photos?_page=$_pageNumber");
            List<Photo> fetchedPhotos = Photo.parseList(json.decode(response.body));
            setState(() {
              _hasMore = fetchedPhotos.length == _defaultPhotosPerPageCount;
              _loading = false;
              _pageNumber = _pageNumber + 1;
              _photos.addAll(fetchedPhotos);
            });
          } catch (e) {
            setState(() {
              _loading = false;
              _error = true;
            });
          }
        }
      }
      
      class Photo {
        final String title;
        final String thumbnailUrl;
        Photo(this.title, this.thumbnailUrl);
        factory Photo.fromJson(Map<String, dynamic> json) {
          return Photo(json["title"], json["thumbnailUrl"]);
        }
        static List<Photo> parseList(List<dynamic> list) {
          return list.map((i) => Photo.fromJson(i)).toList();
        }
      }
      

      无限滚动答案信用和更多信息Infinite Scrolling ListView

      【讨论】:

        【解决方案6】:

        这主要发生在您使用错误的索引值从列表中获取数据时。就我而言,我犯了同样的错误。

        【讨论】:

          【解决方案7】:

          当您在遍历数组时用完值时会发生此错误。在ListView 组件缺少 itemCount 属性的情况下,组件会尝试继续迭代,但不知道何时完成,因此它最终会继续超出范围(数组的长度)。

          在运行设置不佳的for loop 后,您也可能会看到此错误。例如:

          var arr = [1, 2, 3];
          
          for (var i=0; i < 4; i++) {
              print(arr[i]);
          }
          

          此飞镖代码也会导致范围错误。该数组有 3 个项目,但我们尝试迭代 4 次。

          【讨论】:

            【解决方案8】:

            添加属性

                itemCount: list.length,
            

            在 listview.builder 或 gridview.builder 中。

            这个错误对我有用:

            RangeError (index): Invalid value: Not in inclusive range 0..29: 55
            

            【讨论】:

              猜你喜欢
              • 2023-03-03
              • 1970-01-01
              • 2020-07-06
              • 2019-11-01
              • 2021-08-14
              • 2021-10-21
              • 2020-07-05
              • 1970-01-01
              • 2021-01-01
              相关资源
              最近更新 更多