Dart/Flutter - Flutter - Why ListView is going inf

2019-08-19 08:55发布

问题:

Not sure since I have just started building things with Flutter and Dart. If anyone can take a look at the code and can share inputs on:

  • How to display listview having fixed number of items, lets say in my example we are fetching 100 items
  • How to implement paging, lets say initially I want to fetch 1st page and then while scrolling page 2nd and so on.

Issues:

In current implementation, I am finding 2 issues:

  • Able to scroll endlessly at bottom
  • Finding exception in logcat output:

    03-15 06:14:36.464 3938-3968/com.technotalkative.flutterfriends I/flutter: Another exception was thrown: RangeError (index): Invalid value: Not in range 0..99, inclusive: 100

I have posted the same issue on my Github repository: https://github.com/PareshMayani/Flutter-Friends/issues/1

Would appreciate if you contribute to this repo!

回答1:

That is beacuse you are using ListView.builder which actually renders an infinite list when itemCount is not specified. Try specifying itemCount to 100.

For pagination, the simplest solution with a ListView.builder would be to show a refresh widget when the list has reached its end and initiate a refresh api call, and then add new items to the list and increase item count.

Example:

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => new _ExampleState();
}

class _ExampleState extends State<Example> {

  // initial item count, in your case `_itemCount = _friendList.length` initially
  int _itemCount = 10;

  void _refreshFriendList() {
    debugPrint("List Reached End - Refreshing");

    // Make api call to fetch new data
    new Future<dynamic>.delayed(new Duration(seconds: 5)).then((_){
        // after new data received
        // add the new data to the existing list
        setState(() {
          _itemCount = _itemCount + 10; // update the item count to notify newly added friend list
          // in your case `_itemCount = _friendList.length` or `_itemCount = _itemCount + newData.length`
        });
    });
  }

  // Function that initiates a refresh and returns a CircularProgressIndicator - Call when list reaches its end
  Widget _reachedEnd(){
    _refreshFriendList();
    return const Padding(
      padding: const EdgeInsets.all(20.0),
      child: const Center(
        child: const CircularProgressIndicator(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),

      // ListView Builder
      body: new ListView.builder(
        itemCount: _itemCount + 1,
        itemBuilder: (_, index) {
          final Widget listTile = index == _itemCount // check if the list has reached its end, if reached end initiate refresh and return refresh indicator
              ? _reachedEnd() // Initiate refresh and get Refresh Widget
              : new Container(
                  height: 50.0,
                  color: Colors.primaries[index%Colors.primaries.length],
                );
          return listTile;
        },
      ),
    );
  }
}

Hope that helps!

Note: I'm not claiming this is the best way or is optimal but this is one of the ways of doing it. There is an example social networking app of git which does it in a different way, you can take a look at it here.



标签: dart flutter