A Very Good Infinite List Widget created by Very Good Ventures. Great for activity feeds, news feeds, etc. ๐Ÿฆ„

Overview

Very Good Infinite List

Very Good Ventures

Developed with ๐Ÿ’™ by Very Good Ventures ๐Ÿฆ„

ci coverage pub package License: MIT style: very good analysis


A Very Good Infinite List Widget created by Very Good Ventures.

InfiniteList comes in handy when building features like activity feeds, news feeds, or anywhere else where you need to lazily fetch and render content for users to consume.

Example

Usage

A basic InfiniteList requires two parameters:

  • itemLoader which is responsible for asynchronously fetching the content
  • builder which is responsible for returning a Widget given a specific item (result)
import 'package:flutter/material.dart';
import 'package:very_good_infinite_list/very_good_infinite_list.dart';

void main() => runApp(MyApp());

Future<List<String>?> _itemLoader(int limit, {int start = 0}) {
  return Future.delayed(
    const Duration(seconds: 1),
    () => List.generate(limit, (index) => 'Item ${start + index}'),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Infinite List')),
        body: InfiniteList<String>(
          itemLoader: _itemLoader,
          builder: InfiniteListBuilder<String>(
            success: (context, item) => ListTile(title: Text(item)),
          ),
        ),
      ),
    );
  }
}

Customizations

InfiniteList

InfiniteList has multiple optional parameters which allow you to customize the loading and error behavior.

InfiniteList<String>(
  itemLoader: _itemLoader,
  builder: InfiniteListBuilder<String>(...),
  bottomLoader: (context) {
    // Return a custom widget which will be rendered at the bottom of the list
    // while more content is being loaded.
  },
  errorLoader: (context, retry, error) {
    // Return a custom widget which will be rendered when `itemLoader`
    // throws a generic `Exception` and there is prior content loaded.
    // `retry` can be invoked to attempt to reload the content.
  },
  // How long to wait between attempts to load items.
  // Defaults to 100ms.
  debounceDuration: Duration.zero,
  // What percentage of the screen should be scrolled before
  // attempting to load additional items.
  // Defaults to 0.7 (70% from the top).
  scrollOffsetThreshold: 0.5,
);

InfiniteListBuilder

InfiniteListBuilder has multiple optional parameters which allow you to render different widgets in response to various states that the InfiniteList can be in.

InfiniteList<String>(
  itemLoader: _itemLoader,
  builder: InfiniteListBuilder<String>(
    empty: (context) {
      // Return a custom widget when `itemLoader` returns an empty list
      // and there is no prior content.
    },
    loading: (context) {
      // Return a custom widget when `itemLoader` is in the process of
      // fetching results and there is no prior content
    },
    success: (context, item) {
      // Return a custom widget when `itemLoader` has returned content.
      // Here item refers to a specific result.
      // This builder will be called multiple times as different results
      // come into view.
    },
    error: (context, retry, error) {
      // Return a custom widget when `itemLoader` throws an `InfiniteListException`.
      // `error` will also be called when `itemLoader` throws any `Exception`
      // if there is no prior content.
    },
  ),
);

Refer to the example to see both basic and complex usage of InfiniteList.

Comments
  • SliverInfiniteList sometimes requires an extra pull to load more items

    SliverInfiniteList sometimes requires an extra pull to load more items

    Describe the bug My team had a SliverInfiniteList created by @alestiago (thanks Alejandro!!) before it was provided through this package in version 0.5.0. We attempted to swap in the SliverInfiniteList and noticed that by default the SliverInfiniteList sometimes requires an additional pull-up in order to load and display new items when the list reaches the end of what is loaded. We believe this may be due to how the effectiveItemCount is calculated, how the end of the list is determined, and how that results in the display of the loadingBuilder.

    To Reproduce Using a SliverInfiniteList that is the last sliver in a CustomScrollView, which has a loadingBuilder and the ability to load more list items:

    • Quickly scroll through the list
      • The list reaches the end of displayable items and stops scrolling
    • Pull up to attempt to keep scrolling
      • While pulling up, either the loading indicator displays or the list over-scrolls when using iOS BouncingScrollPhysics and shows no indicator
      • New list items are eventually loaded in and scrolling can continue

    Expected behavior What we expected (which reflects the behavior of the custom SliverInfiniteList made by VGV for our team) is that as the user scrolls down the list and reaches the end of the loaded data, the loading indicator (supplied by the loadingBuilder) is displayed at the very bottom of the list, and new list items begin to load. This causes the overall scrolling and loading to flow more naturally and reduces the need for the user to pull up again when the list runs out of displayable entries.

    Additional context Let us know if you'd like videos showcasing the difference in behavior, we're happy to send them to the team if needed.

    bug 
    opened by b-nugent 5
  • CustomScrollView + InfiniteList

    CustomScrollView + InfiniteList

    Is your feature request related to a problem? Please describe. When InfiniteList is used inside a CustomScrollView, it has 2 scroll views, resulting in a weird UX (refer to GIF)

    Describe the solution you'd like Have it working with CustomScrollView

    Describe alternatives you've considered

    • Tried using NestedScrollView but it has the same result as without one
    • Tried using NeverScrollablePhysics but InfiniteList couldn't detect scroll changes and didn't load more items

    Additional context Add any other context or screenshots about the feature request here.

    Screen-Recording-2022-03-18-at-2 55 08-PM

    opened by ezraaaa 3
  • `.separated` factory constructor

    `.separated` factory constructor

    Hello ! I know matching feature parity with a standard Flutter widget is usually pretty tough but I'd love if the .separated constructor was added here to allow users to space their content easily. Conditional padding or space filling widgets are the only alternative and are kind of troublesome to use imho.

    opened by Nolence 3
  • Declarative API Reasoning (Breaking Changes)

    Declarative API Reasoning (Breaking Changes)

    Declarative API Reasoning

    Hi all ๐Ÿ‘‹๐Ÿป

    This is a notice to inform everybody that a breaking change might be coming to this package in the near-future. The new API can be found and tested in the refactor/declarative-api branch.

    The reason for these changes originate from testing done with the package internally. We've determined that the current API, though great for some usages, is not flexible enough for our use cases. In particular, due to the package maintaining its own state, it prohibits easy usage of the declarative nature of the Flutter framework and packages that do the same, such as the bloc library.

    Once further testing is finished, the outstanding branch will be merged in and the version bumped.

    The new API, in its current state, can be outlined like this:

    class InfiniteList<T> extends StatefulWidget {
      final ScrollController scrollController;
      final double scrollExtentThreshold;
      final Duration debounceDuration;
      final bool reverse;
      final List<T> items;
      final bool isLoading;
      final bool hasError;
      final bool hasReachedMax;
      final VoidCallback onFetchData;
      final EdgeInsets padding;
      final WidgetBuilder emptyBuilder;
      final WidgetBuilder loadingBuilder;
      final WidgetBuilder errorBuilder;
      final WidgetBuilder separatorBuilder;
      final Widget Function(BuildContext context, T item) itemBuilder;
    }
    

    If you have any comments or suggestions, please let us know below. Thank you! ๐Ÿ‘‹๐Ÿป

    enhancement 
    opened by jeroen-meijer 3
  • fix: remove need for an extra pull

    fix: remove need for an extra pull

    Description

    Fixes: https://github.com/VeryGoodOpenSource/very_good_infinite_list/issues/41#issuecomment-1278097815

    โš ๏ธ Breaking โš ๏ธ

    Ad a breaking change, this delegates the re-fetching trigger from our custom code (reliant on ScrollPsotion) to the SliverList (SlverCosntraints reliant).

    This will trigger the re-fetching once the last item in the list is built. That should happen when the viewport hits the bottom of the scrollable cache area.

    Now that we rely on the cache area, we don't need scrollExtentThreshold nor the SliverInfiniteList needs to be the last sliver on a CustomScrollView.

    Instead, the user can pass cacheExtent to the InfiniteList to customize the cache area of the internal ScrollView. SliverInfiniteList users can pass that to their own CustomScrollView.

    The cache area is not exactly the same as cacheExtent since it is applied to both edges of the sliver, not only the trailing one.

    Breaking changes:

    Public member defaultScrollExtentThreshold was removed. Any tests and implementations that use it will break.

    Public members InfiniteList.scrollExtentThreshold and SliverInfiniteList.scrollExtentThreshold were removed. Any implementation that specified these values will break.

    Default behavior for InfiniteList.scrollExtentThreshold and SliverInfiniteList.scrollExtentThreshold was to apply defaultScrollExtentThreshold, which was equal to 400 pixels. Now that we rely on cacheExtent, the default value resorts to the frameworks RenderAbstractViewport.defaultCacheExtent. Which is equal to 250 pixels.

    Type of Change

    • [ ] โœจ New feature (non-breaking change which adds functionality)
    • [x] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [x] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore
    bug 
    opened by renancaraujo 2
  • scrollDirection parameter

    scrollDirection parameter

    Is your feature request related to a problem? Please describe. I had to configure scroll direction on one of my projects and while using this library i found it had no such parameter. this commit just adds that option to this library.

    Describe the solution you'd like Simply adds another parameter scrollDirection which is found in Flutter's ListView constructor to the library

    good first issue 
    opened by ArunPrakashG 2
  • refactor!: declarative api

    refactor!: declarative api

    Description

    This PR refactors the API to use a more declarative approach, as described in #14. It includes a version bump to 0.4.0.

    TODO

    • [x] Add more tests.
    • [x] Ensure 100% code coverage.
    • [x] Update documentation.
    • [x] Improve/otherwise update example project.
    • [ ] Upload to pub.

    Type of Change

    • [ ] โœจ New feature (non-breaking change which adds functionality)
    • [ ] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [x] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [x] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore
    opened by jeroen-meijer 2
  • feat: nndb migration

    feat: nndb migration

    Description

    Migrate this package to null safety.

    Type of Change

    • [ ] โœจ New feature (non-breaking change which adds functionality)
    • [ ] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [ ] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore
    enhancement 
    opened by Abhishek01039 2
  • feat: add sliver infinite list

    feat: add sliver infinite list

    Description

    Add silver infinite list. Change implementation to be based on slivers.

    Motivation

    Reference: #28

    In order to allow the infinite list to work in a CustomScrollView, a sliver version of it shall be done.

    Implemmentation details

    This PR introduces SliverInfiniteList widget as a sliver version of the existing InfiniteList widget.

    The current "re-fetch" logic, when based on scroll changes, is coupled with the compact of the widget being the only scrollable widget in a scroll context. In other words, it counts on the fact that it contains the underlying ScrollView.

    To support the scenario where the infinite list is in an external scroll context (user-controlled CustomScrollView), the "re-fetch" logic, when based on scroll changes, takes information from an existing ScrollPosition from the wrapping Scrollable. A mounted sliver is guaranteed to have a scrollable wrapping it. Using ScrollPosition from scrollable over one from a ScrollController improves the reliability of the package since a user can inform the same ScrollController to multiple ScrollViews, making the controller poses more than one ScrollPosition.

    To avoid code duplication, The existing InfiniteList widget has moved from using an internal ListView to using its own CustomScrollView wrapping the new SliverInfiniteList and then SliverInfiniteList takes care of the "re-fetch" logic, delegating InfiniteList to mere decorative roles, such as adding padding.

    InfiniteList is expected to work identically as before this PR, even with its internal changes. To preserve previous behavior, a custom "padding" logic from the media query was added to it.

    API changes

    • Addition: Since it is a sliver, SliverInfiniteList cannot guarantee that the scroll direction is vertical. So ScrollDirection was added to InfiniteList since SliverInfiniteList natively already supports horizontal scroll.
    • Breaking: Since it is not composed of ListView anymore, any test containing InfiniteList that queries for a ListView will break.
    • Breaking: Any ScrollController passed to InfiniteList is now merely a passthrough property. Any implementation or test that expects it to have a listener on InfiniteList will break.
    • Breaking: InfiniteList is now a stateless widget.
    • Addition: default values were added to global constants to be sued by both widgets (sliver and non sliver).

    Sliver limitations

    SliverInfiniteList has to be the last sliver informed to a CustomScrollView since the "re-fetch" logic is triggered only when the scroll reaches the end of the scroll view, not the end of SliverInfiniteList.

    Going around that limitation will require a much, much more complex change. Reimplementing SliverList to inform its current extent (which is known only after the layout phase) and check against ScrollPosition.pixels.

    Type of Change

    • [x] โœจ New feature (non-breaking change which adds functionality)
    • [ ] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [x] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore
    enhancement 
    opened by renancaraujo 1
  • Add scroll direction parameter

    Add scroll direction parameter

    Description

    Type of Change

    • [x] โœจ New feature (non-breaking change which adds functionality)
    • [ ] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [ ] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore

    Adds scrollDirection parameter to the default constructor, by default the value is the default of ListView parameter, Axis.vertical

    Implements #20

    opened by ArunPrakashG 1
  • chore: v0.7.0

    chore: v0.7.0

    Description

    • chore: v0.7.0

    Type of Change

    • [ ] โœจ New feature (non-breaking change which adds functionality)
    • [ ] ๐Ÿ› ๏ธ Bug fix (non-breaking change which fixes an issue)
    • [ ] โŒ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] ๐Ÿงน Code refactor
    • [ ] โœ… Build configuration change
    • [ ] ๐Ÿ“ Documentation
    • [ ] ๐Ÿ—‘๏ธ Chore
    chore 
    opened by felangel 0
  • Support Flutter Infinite Integration with Flutter Bloc

    Support Flutter Infinite Integration with Flutter Bloc

    Is your feature request related to a problem? Please describe.

    Often to fetch infinite data I use state management like bloc, and when I use ery_good_infinite_list I need Future to fetch data. And this will be completely different when using bloc.

    Describe the solution you'd like

    And this is an example of the implementation when using Bloc, maybe this can be a reference but for the implementation maybe you know better.

    return BlocBuilder<SampleBloc, SampleState>(
          builder: (context, state) {
            return InfiniteList<String>(
              builder: InfiniteListBuilder<String>(
                success: (context, data) => Text('Success'),
                empty: (context) => Text('Empty'),
                error: (context, retry, error) => Text('Error'),
                loading: (context) => Text('Loading'),
              ),
              data: state is SampleSuccess ? state.data : '',
              isSuccess: state is SampleSuccess,
              isFailure: state is SampleFailure,
              isLoading: state is SampleLoading,
              itemLoader: () {
                // TODO: fetch data
              },
            );
          },
        );
    

    Describe alternatives you've considered

    Additional context

    opened by wisnuwiry 0
  • Support for two-way Pagination

    Support for two-way Pagination

    Currently VeryGoodInfiniteList is unable to be used for the chat message list as it only supports bottom pagination. A chat message list requires both top and bottom pagination in order to work perfectly.

    It would be really great if VeryGoodInfiniteList supports two-way Pagination.

    opened by xsahil03x 0
Releases(v0.7.0)
  • v0.7.0(Nov 28, 2022)

  • v0.6.0+1(Oct 14, 2022)

  • v0.6.0(Oct 14, 2022)

  • v0.5.0(Sep 26, 2022)

  • v0.4.1(May 17, 2022)

  • v0.4.0(Feb 28, 2022)

    What's Changed

    • chore: add @jeroen-meijer to CODEOWNERS by @jeroen-meijer in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/17
    • docs: update vgv logo by @felangel in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/22
    • docs: use very good brand assets by @felangel in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/24
    • refactor!: declarative api by @jeroen-meijer in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/15
    • ci: use VeryGoodWorkflows@v1 by @felangel in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/25

    New Contributors

    • @jeroen-meijer made their first contribution in https://github.com/VeryGoodOpenSource/very_good_infinite_list/pull/17

    Full Changelog: https://github.com/VeryGoodOpenSource/very_good_infinite_list/compare/v0.3.0...v0.4.0

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Apr 5, 2021)

  • v0.2.1(Feb 19, 2021)

  • v0.2.0(Feb 18, 2021)

Owner
Very Good Open Source
Open Source Code from Very Good Ventures (@VGVentures)
Very Good Open Source
HSV(HSB)/HSL/RGB/Material color picker inspired by all the good design for your amazing flutter apps.

flutter_colorpicker HSV(HSB)/HSL/RGB/Material color picker inspired by all the good design for your amazing flutter apps. Adorable color pickers out o

Dark Knight 279 Dec 30, 2022
DirectSelect is a selection widget with an ethereal, full-screen modal popup displaying the available choices when the widget is interact with. https://dribbble.com/shots/3876250-DirectSelect-Dropdown-ux

direct-select-flutter DirectSelect is a selection widget with an ethereal, full-screen modal popup displaying the available choices when the widget is

null 582 Jan 4, 2023
A Horizontal List view With Lots of modification including a scaled current item.

Pub.dev Scaled List A Horizontal List view With Lots of modification including a scaled current item. Provided with curved custom painting and Dots in

Hosain Mohamed 35 Nov 5, 2022
A flutter package to display a country, states, and cities. In addition it gives the possibility to select a list of countries, States and Cities depends on Selected, also you can search country, state, and city all around the world.

A flutter package to display a country, states, and cities. In addition it gives the possibility to select a list of countries, States and Cities depends on Selected, also you can search country, state, and city all around the world.

Altaf Razzaque 25 Dec 20, 2022
Flutter package designed to select an item from a list, with the option to filter and even search the items online.

select_dialog Package Package designed to select an item from a list, with the option to filter and even search the items online. Versions Non Null Sa

David Araujo 63 Dec 10, 2022
Code for the screens created with flutter

FlutterUI-Emojis Code for the screens created with Flutter. Design Credit - https://dribbble.com/shots/9094050-Online-Reservation/attachments/1177787?

Raja Yogan 55 Oct 27, 2022
Code for the app created with flutter

Curved Design Code for a simple ui screen created with flutter. Design credit - https://dribbble.com/shots/6687016-Foody-Food-by-Subscription How do I

Raja Yogan 256 Dec 11, 2022
A ecommerce app created in flutter implementing the features add to cart, total ,add, remove item and a login function

catalog A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if t

null 0 Nov 27, 2021
A simple animated radial menu widget for Flutter.

flutter_radial_menu A radial menu widget for Flutter. . Installation Install the latest version from pub. Quick Start Import the package, create a Rad

Victor Choueiri 434 Jan 7, 2023
Custom widget for Flutter

Flushbar Use this package if you need more customization when notifying your user. For Android developers, it is made to substitute toasts and snackba

Andre Haueisen 899 Dec 30, 2022
flutter stepper_touch widget

stepper_touch the concept of the widget inspired from Nikolay Kuchkarov. i extended the functionality to be more useful in real world applications Tha

Raouf Rahiche 271 Dec 30, 2022
A TypeAhead widget for Flutter, where you can show suggestions to users as they type

Flutter TypeAhead A TypeAhead (autocomplete) widget for Flutter, where you can show suggestions to users as they type Features Shows suggestions in an

null 661 Jan 5, 2023
A highly customisable Flutter widget for entering pin code. Suitable for use cases such as login and OTP.

pin_code_text_field It's a beautiful and highly customizable Flutter widget for entering pin code. Suitable for use cases such as login and OTP. Usage

Liew Jun Tung 309 Dec 28, 2022
Flutter FoldingCell widget

Simple FoldingCell widget Simple folding cell widget, pass frontWidget and innerWidget to fold and unfold. Installation Add dependency in pubspec.yaml

Farrukh 513 Dec 30, 2022
Scratch card widget which temporarily hides content from user.

scratcher Scratch card widget which temporarily hides content from user. Features Android and iOS support Cover content with full color or custom imag

Kamil Rykowski 405 Dec 27, 2022
A simple widget for animating a set of images with full custom controls as an alternative to using a GIF file.

image_sequence_animator A simple widget for animating a set of images with full custom controls as an alternative to using a GIF file. If you have a G

AliYigitBireroglu 134 Dec 22, 2022
Animated Selection Slide Sezgin BilgetayAnimated Selection Slide An animated selection widget by swiping by Sezgin Bilgetay.

Animated Selection Slide This flutter project allows you to make your choices with animation in inbox. For UI, it's inspired by the great example on d

null 340 Jan 7, 2023
A Flutter package that provides an Emoji picker widget with 1500+ emojis in 8 categories.

emoji_picker_flutter Yet another Emoji Picker for Flutter ?? Note: This package is based on emoji_picker which has been deprecated and not maintained

Stefan Humm 99 Dec 24, 2022
A Flutter Widget Approach for using HTML tags & CSS styles in your upcoming Apps.

html_widgets A Flutter Widget Approach for using HTML tags & CSS styles in your upcoming Apps. Text Widgets *text property is required for all the tex

XenonLabz 7 Jul 14, 2022