颤振错误:RangeError(索引):无效值:不在0..2范围内,包括:3

Posted

技术标签:

【中文标题】颤振错误:RangeError(索引):无效值:不在0..2范围内,包括:3【英文标题】:Flutter Error: RangeError (index): Invalid value: Not in range 0..2, inclusive: 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()构造函数 【参考方案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

【讨论】:

以上是关于颤振错误:RangeError(索引):无效值:不在0..2范围内,包括:3的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - RangeError(索引):无效值:有效值范围为空:0

RangeError(索引):无效值:不在 0..6 范围内,包括:-2

RangeError(索引):无效值:不在 0..7 范围内,包括:8

Flutter:DioError [DioErrorType.DEFAULT]:RangeError(索引):无效值:只有有效值为0:

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

Flutter:RangeError(索引):无效值:不在0..14范围内,包括:15