Hello world, today we’ll look at a feature present in so many apps that it is kind of mandatory to know how to implement it. There are several packages out there that could be used to implement this feature, though it could easily be implemented without any library. Let’s implement Infinite Scroll in Flutter without any package.
I made a little sample for this tutorial, and you can find the source code here, in my github repo.
Implementation
It is extremely easy to implement this feature. I’ll divide its implementation into simple steps easy to follow.
If you find this article useful, please follow me on Twitter, Github, Linkedin, or like my Facebook page to stay updated.Follow me on social media and stay updated
1- Creating the Items Source
First, the items in our list view must come from somewhere. We create a method to simulate a data source (API, Database…) I added a simple method that creates a list of items, based on two parameters PageSize (The size of each page returned to the listview), skip (The number of items already returned to the listview). This method returns the list of items requested, and a boolean value named “hasNext” specifying if there are items left in the list or not.
1 2 3 4 5 6 7 8 9 10 11 | (List<SampleItem> items, bool hasNext) getItems(int pageSize, int skip) { int maxPageCount = 3; bool hasNext = (pageSize * maxPageCount) > skip; return ( List.generate(pageSize, (index) => SampleItem(index + skip)), hasNext, ); } |
2- Adding Items to the ListView
We then add the items to the listview, BUT, we do this in such a way that if there are more items left in our pseudo server, then the last item in our listview should be a loader (indicating to the user that we still have items left that are loading and will soon appear). We do this by adding a +1 to the items count, when initializing the listview and when rendering items, we tell the list view to render a loader at the index of the last item.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | final totalItems = widget.hasNext ? widget.items.length + 1 : widget.items.length; ... body: ListView.builder( itemCount: totalItems, controller: _scrollController, itemBuilder: (BuildContext context, int index) { if (index == widget.items.length) { return const Center( child: SizedBox( height: 50, child: Center(child: CircularProgressIndicator())), ); } final item = widget.items[index]; return ListTile( title: Text('SampleItem ${item.id}'), leading: const CircleAvatar( // Display the Flutter Logo image asset. foregroundImage: AssetImage('assets/images/flutter_logo.png'), ) ... |
3- Listening to the ListView Scroll and Trigger Infinite Scroll when required
Next, we have to listen to the listview scroll, when we detect that it scrolled to the end, if the server has items left in it, we trigger an infinite scroll to display the rest of items in the list. This is done with a ScrollController.
1 2 3 4 5 6 7 8 9 | final ScrollController _scrollController = ScrollController(); @override void initState() { _scrollController.addListener(_onScrollListener); super.initState(); } |
We then listen to scroll events, detect if the scroll has reached its maximum, and load the rest of the list appropriately.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void _onScrollListener() { if (!widget.hasNext) { return; } if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { setState(() { final result = getItems(_pageSize, widget.items.length); widget.items.addAll(result.$1); widget.hasNext = result.$2; }); } } |
Conclusion
That is how easy it was to implement infinite scroll. And no package was required! I hope this helped, and please, don’t hesitate to share this post if you liked, thanks! Once again, the source code is on Github
Follow me on social media and stay updated