An extension of the Flutter ListView widget for incrementally loading items upon scrolling

Last update: Jun 20, 2022

incrementally_loading_listview

pub package

An extension of the Flutter ListView widget for incrementally loading items upon scrolling. This could be used to load paginated data received from API requests.

NOTE: this package depends on rxdart. If you run into conflicts with different versions of rxdart, consider using dependency overrides as per this link

Getting Started

There's a working example that can be run to see how it works.

First import the library

import 'package:incrementally_loading_listview/incrementally_loading_listview.dart';

You can then use the IncrementallyLoadingListView widget in a similar way you would with the ListView.separated constructor

return IncrementallyLoadingListView(
    hasMore: () => _hasMoreItems,
    itemCount: () => items.length,
    loadMore: () async {
        // can shorten to "loadMore: _loadMoreItems" but this syntax is used to demonstrate that
        // functions with parameters can also be invoked if needed
        await _loadMoreItems();
    },
    loadMoreOffsetFromBottom: 2,
    itemBuilder: (context, index) {
        /// your builder function for rendering the item
    },
    separatorBuilder: (context, index) {
        /// your builder function for rendering the separator
    }
);

The widget allows passing in the same parameters you would to the ListView.builder constructor but itemCount is required so that when an item scrolls into view, it can see if it should attempt to load more items. Note that this is a callback that returns a boolean rather than being a boolean value. This allows the widget to not require a reference/copy of your data collection. The other parameters that can be specified are

  • hasMore: a callback that indicates if there are more items that can be loaded
  • loadMore: a callback to an asynchronous function that loads more items
  • loadMoreOffsetFromBottom: determines when the list view should attempt to load more items based on of the index of the item is scrolling into view. This is relative to the bottom of the list and has a default value of 0 so that it loads when the last item within the list view scrolls into view. As an example, setting this to 1 would attempt to load more items when the second last item within the list view scrolls into view
  • onLoadMore: a callback that is triggered when more items are being loaded. At first this will pass a boolean value of true to when items are being loaded by triggering the loadMore callback function. You could use this to update your UI to show a loading indicator
  • onLoadMoreFinished: a callback that is triggered when items have finished being loading. You can use this to hide your loading indicator
  • separatorBuilder: not required builder function that place separator between items

Providing onLoadMore and onLoadMoreFinished callbacks means the widget doesn't make assumptions on how you want to render a loading indicator so it will be up to your application to handle these callbacks to render the appropriate UI.

GitHub

https://github.com/MaikuB/incrementally_loading_listview
Comments
  • 1. equivalent incrementally_loading_listview for Slivers

    Currently this library is not compatible w/ Slivers. Slivers are used often when you have complex scrolling views or even just a scrolling app bar.

    I think it would be awesome to create a similar incrementally_loading_listview but for usages in Slivers. That way this library can be used in even more scenarios.

    Reviewed by wemped at 2019-06-18 20:56
  • 2. Loading callbacks not firing when inside FutureBuilder

    I have a somewhat weird issue around loading indicators and this widget. In one part of my app, I load a rather sizable list from the server, so I display a loading indicator using a FutureBuilder<http.Response>, so that the app shows something while the fetch is underway, then switch to this ListView once I have the data. This is the code in question:

    FutureBuilder<http.Response>(
      future: _initialGet, // set to a Future in the `initState()` method
      builder: (BuildContext context, AsyncSnapshot<http.Response> snapshot) {
        if (snapshot.hasData) {
          http.Response response = snapshot.data;
          print(response.statusCode);
          SearchResults results = SearchResults.fromBuffer(response.bodyBytes);
          _cursor = results.cursor;
          _hasMore = results.hasMore;
          _updateList(results.sites); // this method updates the `_items` list used below
    
          return Container(
            key: Key("generalList"),
            child: IncrementallyLoadingListView(
              key: ValueKey(_items),
              shrinkWrap: false,
              itemCount: () => _items.length,
              hasMore: () => _hasMore,
              loadMoreOffsetFromBottom: 5,
              itemBuilder: (context, index) {
                // create tile
              },
              loadMore: () async {
                // load more stuff
              },
            ),
          );
        } else if (snapshot.hasError) {
          // Only for debug and testing really
          return Container(
            key: Key("generalList"),
            child: Text("${snapshot.data.statusCode}"),
          );
        } else {
          // Loading indicator
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                child: CircularProgressIndicator(),
                width: 60,
                height: 60,
              ),
              const Padding(
                padding: EdgeInsets.only(top: 16),
                child: Text('Loading...'),
              )
            ],
          );
        }
      },
    )
    

    The loading indicator appears and disappears, the list is created, and has all the items I loaded. However, the callbacks, namely loadMore don't seem to fire when the end of the list is reached - a breakpoint set in that function is never hit. The same does not happen when outside the FutureBuilder.

    Is it possible the FutureBuilder is somehow interfering with detecting the end of the list?

    Reviewed by zmeggyesi at 2020-01-23 06:44
  • 3. Is there anyway to remove the RxDart dependency?

    I see that it uses PublishSubject. Is there any alternative for this without using RxDart? Like using StreamController perhaps?

     final PublishSubject<bool> _loadingMoreSubject = PublishSubject<bool>();
      Stream<bool> _loadingMoreStream;
    
      IncrementallyLoadingListViewState() {
        _loadingMoreStream =
            _loadingMoreSubject.switchMap((shouldLoadMore) => loadMore());
      }
    

    It's just that I don't want to add RxDart to my app just for this ListView.

    Reviewed by abdhoms at 2020-07-02 22:21
  • 4. Rxdart conflict

    When I try to install the 0.04 version of the package in pubspec.yaml, I get this error:

    Because flutter_google_places >=0.1.3 depends on rxdart ^0.19.0 and incrementally_loading_listview >=0.0.4 depends on rxdart ^0.18.1, flutter_google_places >=0.1.3 is incompatible with incrementally_loading_listview >=0.0.4. So, because my_project depends on both incrementally_loading_listview ^0.0.4+3 and flutter_google_places ^0.1.3, version solving failed.

    Do someone nkow how to fix it well? Thanks!

    Reviewed by GENL at 2019-01-15 08:28
  • 5. [Feature proposal] Conserve scroll momentum

    This is probably hard to do, but it would be very nice if you could scroll down in one big motion, stopping until hitting the last fetched entry, and then continuing to scroll down (maybe less quickly) after the remaining content has been fetched.

    I am not 100% sure how that would feel like, so I would like to have a bit of an discussion, has anyone ever seen that behaviour in another app?

    Reviewed by StefanLobbenmeier at 2019-03-14 16:08
  • 6. Performance question

    I can't test it out right now and am just looking for useful resources/libraries for my current project.

    I am curious on how it performs with huge sets of data. Does it allocate and keep every newly generated list entry in memory? Not sure if you are familiar with the android ecosystem, but there is a component called RecyclerView that basically re-uses the UI elements and only changes the data that they display, making it super memory efficient and reduces the lag created by allocating all UI elements and keeping them alive.

    Thanks!

    Reviewed by mainrs at 2018-10-28 15:41
  • 7. update rxdart dependency

    I was getting some version solving errors while using this library in my own project, noticed it was because rxdart was more out of date than another library I'm using. Thought I'd update it for you, tried to follow your structure for updates best I could.

    Nothing in the rxdart changelog looks like it affects this project so it should be low to 0 risk.

    Reviewed by wemped at 2019-06-07 16:30
  • 8. Positional insert / updates

    I need to update rows in the list as new rows pushed to the app. But I need to not just add them at the bottom but rather in any previous location that I scrolled past.

    The ops would be: Insert Update Delete.

    Thinking about how best to extend the code to support this.

    The data coming in must know it's position. This is a sequence key unique to each table.

    1. Just buffer all data on the client and so do the insert / update / delete into the buffer. The list then just reads from the buffer as the user scrolls up and down. This keeps the logic away from the list

    2. Maybe you have an idea on another approach

    Reviewed by ghost at 2019-03-29 17:45
  • 9. Loading indicator widget

    Hi,

    thanks for the great library! Is it possible to specify the loading indicator widget somehow (in a RefreshIndicator fashion or any custom widget)? That would be really useful to display at the bottom of the list, while data is loading.

    Reviewed by divan at 2019-03-13 17:47
  • 10. SQFLite Implementation

    Is this package also fit to SQFlite data fetching ?

    In my case, I may have thousands of transaction records, which clearly are not required to pop all at once.

    What's your opinion ?

    Thanks

    Reviewed by ejabu at 2018-08-31 03:51
  • 11. use in futurebuilder

    Merhaba, futurebuilder içinde "IncrementallyLoadingListView" kullanıyorum. Fakata future sürekli çalışmaya devam ediyor. Bunun için ne yapabilirim. futuru: api_post Here information comes from the service and makes hundreds of requests per second.

    Reviewed by ishakdas at 2021-02-28 11:51

Related

Flutter Bidirectional ListView - ListView with items that can be scrolled in both directions with a fixed item count and scroll boundaries.
Flutter Bidirectional ListView - ListView with items that can be scrolled in both directions with a fixed item count and scroll boundaries.

Flutter Bidirectional ListView ListView with items that can be scrolled and lazy loaded in up and down direction with a fixed item count and scroll bo

May 30, 2022
The ROHD Verification Framework is a hardware verification framework built upon ROHD for building testbenches.
The ROHD Verification Framework is a hardware verification framework built upon ROHD for building testbenches.

ROHD Verification Framework The ROHD Verification Framework (ROHD-VF) is a verification framework built upon the Rapid Open Hardware Development (ROHD

Jun 24, 2022
This is an applications for fetching pokemon data from API and showed in Listview with infinity scrolling
This is an applications for fetching pokemon data from API and showed in Listview with infinity scrolling

pokedex This is an applications for fetching pokemon data from API and showed in Listview with infinity scrolling #Author Created by Yusril Rapsanjani

Dec 13, 2019
A Flutter ListView in which items can be grouped into sections.
A Flutter ListView in which items can be grouped into sections.

Grouped list package for Flutter. Now with beta support for null safety! A flutter ListView in which list items can be grouped to sections. Features S

Jun 21, 2022
A ListView that allows you to group list items and support headers like iOS UITableView section.
A ListView that allows you to group list items and support headers like iOS UITableView section.

GroupListView package for Flutter. A ListView that allows you to group list items and support headers like iOS UITableView section. Features List Item

Jun 17, 2022
A loading more list which supports ListView,GridView,WaterfallFlow and Slivers.

loading_more_list A loading more list which supports ListView,GridView,WaterfallFlow and Slivers. Language: English | 中文简体 Web demo for LoadingMoreLis

Jun 23, 2022
A flutter widget that animates scrolling through a set of fixed size containers.
A flutter widget that animates scrolling through a set of fixed size containers.

Spinner This flutter package implements a simple Spinner animation that cycles through any number of fixed size child widgets. Useful for selecting a

Aug 3, 2021
Flutter base code for app with slivers for affect on app bar and scrolling of cards.

scroll_with_flexi_title A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you

Dec 28, 2021
Flutter plugin to implement a Boom Menu, with icons, title, subtitle, animated FAB Icons and hide on scrolling.
Flutter plugin to implement a Boom Menu, with icons, title, subtitle, animated FAB Icons and hide on scrolling.

Flutter Boom Menu Usage The BoomMenu widget is built to be placed in the Scaffold.floatingActionButton argument, replacing the FloatingActionButton wi

Apr 29, 2022
OrderFoody - A template with command buttons in horizontal scrolling list
OrderFoody - A template with command buttons in horizontal scrolling list

order_coffee In this project you create a template with command buttons in horiz

Jun 22, 2022
Flutter tableview - A flutter widget like iOS UITableview. let listView with section header and each section header will hover at the top.
Flutter tableview - A flutter widget like iOS UITableview. let listView with section header and each section header will hover at the top.

中文 flutter_tableview A flutter widget like iOS UITableview. let listView with section header and each section header will hover at the top. Installing

May 10, 2022
🧾 Flutter widget allowing easy cache-based data display in a ListView featuring pull-to-refresh and error banners.

Often, apps just display data fetched from some server. This package introduces the concept of fetchable streams. They are just like normal Streams, b

Jan 18, 2022
Multi type list view - A flutter customer ListView that displays multiple widget types.
Multi type list view - A flutter customer ListView that displays multiple widget types.

MultiTypeListView A light weight flutter customer ListView that displays multiple widget types. Screenshot home chat Getting Started dependencies: m

Jan 27, 2022
A ListView widget capable of pinning a child to the top of the list.

PinnableListView A Flutter ListView widget that allows pinning a ListView child to the top of the list. Demo Getting Started Define the list PinCont

May 17, 2020
Flutter_load_widget - Global Flutter loading widget
Flutter_load_widget - Global Flutter loading widget

load Global loading widget, which can be used through simple configuration. Pure flutter library, not use native code. It is similar to OKToast in use

Apr 20, 2022
Loading_animation_widget - Flutter loading animation widget.
Loading_animation_widget - Flutter loading animation widget.

How to use Add loading_animation_widget: to your pubspec.yaml dependencies then run flutter pub get dependencies: loading_animation_widget: Then im

Jun 27, 2022
A flutter widget to indicate loading progress. Easy to use, easy to extend

?? ?? ?? A flutter widget to indicate loading progress. Easy to use, easy to extend

May 30, 2022
A package that gives us a modern way to show animated border as a placeholder while loading our widget with easy customization and ready to use.
A package that gives us a modern way to show animated border as a placeholder while loading our widget with easy customization and ready to use.

A package that gives us a modern way to show animated border as a placeholder while loading our widget with easy customization and ready to use.

Jun 10, 2022