Flutter: Adding Infinity Scroll

Abhijeet Mohapatra
Smartters’ Studio
3 min readNov 16, 2020



Retro Infinity Scroll is the go-to listview for your application. This plugin not only has almost all the required features you need but also is enabled with all sorts of customization to get out of your comfort zone and build something innovative. Retro Infinity Scroll is enabled with auto pagination (lazy loading), a swipe to refresh feature with a basic/customized swipe to refresh widget, and some basic customized widgets which we usually require like when the data is loading, or the list is empty or is having some error.

In this article, I will be showing you how to implement all the above-stated features using the Retro Infinity Scroll Plugin.

Step 1:

Add the dependency to your pubspec.yaml file. You can get the latest version from https://pub.dev/packages/retro_infinity_scroll.

retro_infinity_scroll: <latest version>

You can install the package via command line:

$ flutter pub get

Step 2:

Import the following package in your file:

import ‘package:retro_infinity_scroll/retro_infinity_scroll.dart’;

And the fun part is you are done with all the configuration required now you are just ready to code.

Step 3:

You can add any HTTP client to manage network calls. Here I’m using the HTTP package. For more on network calls you can refer

Step 4:

Then create a stateful widget with its state and declare the state variables as per requirements.

bool _hasMore; // determines if more to load
bool _error;
bool _loading;
final int _limit = 10; // max count of data to show on the list
List<String> _photos;

Step 5:

Create a method to get the data from the API.

void fetchData() {
final url = 'https://jsonplaceholder.typicode.com/photos?_page=1';
http.get(url).then((value) {
List<String> fetchedPhotos = List<String>.from(
json.decode(value.body).map((e) => e['thumbnailUrl']));
setState(() {
_hasMore = fetchedPhotos.length == _limit;
_loading = false;
}).catchError((err) {
setState(() {
_error = true;
}).whenComplete(() {
setState(() {
_loading = false;

Step 6:

Now we’re ready to put our RetroInfinityScroll in the build()

body: RetroInfinityScroll(
hasMore: _hasMore,
itemCount: _photos.length,
stateType: _loading
? InfiniteScrollStateType.loading
: _error
? InfiniteScrollStateType.error
: InfiniteScrollStateType.loaded,
errorWidget: Text('Some Error Occurred'),
emptyWidget: Text('No Photos Found'),
loadingWidget: CircularProgressIndicator(),
loadMoreWidget: CircularProgressIndicator(),
onRefresh: () => fetchData(), // Implements network call on swipe refresh
onLoadMore: () => fetchData(), // Implements loadmore
refreshIndicatorType: RefreshIndicatorType.android,
itemBuilder: (ctx, position) => Card(
child: Image.network(
fit: BoxFit.fitWidth,
width: double.infinity,
height: 160,

If you want to use a customized widget for swipe refresh then do implement the refreshIndicatorBuilder and instead of using RefreshIndicatorType.android or RefreshIndicatorType.ios in refreshIndicatorType, you can simply pass RefreshIndicatorType.custom.


Now our small implementation tutorial of this awesome plugin is complete. I hope that this adds a quality amount of information to you.

You can follow me on Twitter and LinkedIn. Also, don’t forget to check out our Website. Thank you for reading, if you enjoyed the article make sure to show me some love by hitting that clap (👏) button!

Happy coding…

Abhijeet Mohapatra