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

AndroidFlutterDart

Android Problem Overview


I am using a long list in Flutter. All the items are rendering fine but I also receive the following error:

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

The following is my code:

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

The following is my getList() method:

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

And the following is my getListItem() method:

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

the following is the screenshot of error:

enter image description here

Android Solutions


Solution 1 - Android

You should pass the itemCount parameter to the ListView.builder to allow it to know the item count

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;
}

Solution 2 - Android

This error occurs when you run out of values when iterating over an array. In the case of the ListView component missing the itemCount prop, the component attempts to continue to iterate but is unaware when to complete so it eventually continues on out of range (the length of the array).

You could also see this error after running a poorly set up for loop. For example:

var arr = [1, 2, 3];

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

This dart code would result in a range error as well. The array has 3 items yet we attempt to iterate 4 times.

Solution 3 - Android

Add the attribute

    itemCount: list.length,

in the listview.builder or gridview.builder.

It works for me on this error:

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

Solution 4 - Android

If you are using StreamBuilder then you must use this line of code:

  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];
 },
                      );
                    }
                   
                  },
                ),

Solution 5 - Android

In my case, my itemCount:list.lenght parameter was fine but somewhere in my listTile, I used wrong parameter for list.indexWhere() function .When I fix function, error was gone.

Solution 6 - Android

For Limited Scroll

The solution is simple you just have to add itemCount to the builder so that the builder allows it to know the item count. Just like the above Code As stated in the this answer

For Infinite Scroll

To do Infinite Scroll use ListView.builder without specifying the itemCount parameter.

  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());
      }
    },
  ),

Full code example

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();
  }
}

to infinite scroll answer credit and for more info Infinite Scrolling ListView

Solution 7 - Android

This mainly occurs when you are using wrong index value to fetch data from list. in my case, I was doing the same mistake.

Solution 8 - Android

I had this problem inside a GridView, but it had nothing to do with my GridView. I was splitting addresses by commas, ex addresses[index].split(',')[0], but I came across a address that had no commas which is why I suddenly got this error. Look closely through the debug console to find the exact line of the error, and test every piece of code in your GridView to pinpoint the error.

Solution 9 - Android

Widget getListView(){
  var itemList = getListElement();
   var list = ListView.builder(
     itemCount: itemList.length,
       itemBuilder:(context, index){
         return ListTile(
           title: Text(itemList[index]),   
         );
         }
   );
   return list;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMuhammad FaizanView Question on Stackoverflow
Solution 1 - AndroidmuttonlambView Answer on Stackoverflow
Solution 2 - AndroidgrimmmView Answer on Stackoverflow
Solution 3 - AndroidNisha JainView Answer on Stackoverflow
Solution 4 - AndroidbentenView Answer on Stackoverflow
Solution 5 - AndroidreplappView Answer on Stackoverflow
Solution 6 - AndroidParesh MangukiyaView Answer on Stackoverflow
Solution 7 - AndroidAshishView Answer on Stackoverflow
Solution 8 - AndroidAugust KimoView Answer on Stackoverflow
Solution 9 - AndroidChintan PatelView Answer on Stackoverflow