loading_more_list 0.1.5

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new45

loading_more_list

pub package

easily build loading more list

Chinese bolg

how to use it

1. prepare for loading more collection

First, you need to extend LoadingMoreBase and override getData method to get your list item. if you want to override loadMore method, please take care of staus in this method.

class TuChongRepository extends LoadingMoreBase<TuChongItem> {
  int pageindex = 1;

  @override
  // TODO: implement hasMore
  bool _hasMore = true;
  bool get hasMore => _hasMore && length < 20;

  @override
  Future<bool> onRefresh() async {
    // TODO: implement onRefresh
    pageindex = 1;
    return loadMore();
  }

  @override
  Future<bool> getData() async {
    // TODO: implement getData
    String url = "";
    if (this.length == 0) {
      url = "https://api.tuchong.com/feed-app";
    } else {
      int lastPostId = this[this.length - 1].post_id;
      url =
          "https://api.tuchong.com/feed-app?post_id=${lastPostId}&page=${pageindex}&type=loadmore";
    }
    bool isSuccess = false;
    try {
      //to show loading more clearly, in your app,remove this
      await Future.delayed(Duration(milliseconds: 500, seconds: 1));

      var result = await HttpFactory.getInstance().getHttpClient().get(url);

      var source = TuChongSource.fromJson(json.decode(result.body));
      if (pageindex == 1) {
        this.clear();
      }

      source.feedList.forEach((item) {
        if (item.hasImage && !this.contains(item) && hasMore) {
          this.add(item);
        }
      });

      _hasMore = source.feedList.length != 0;
      pageindex++;
      isSuccess = true;
    } catch (exception) {
      isSuccess = false;
      print(exception);
    }
    return isSuccess;
  }
}

2.loading more for ListView/GridView

ListConfig for ListView/Grid

 final Widget Function(BuildContext context, T item, int index) itemBuilder;

itemBuilder is used to get how a item like.

  //source list
  final LoadingMoreBase<T> sourceList;

sourceList is the source of list.

class ListConfig<T> extends LoadingMoreListConfig<T> {
  final Axis scrollDirection;
  final bool reverse;
  final ScrollController controller;
  final bool primary;
  final ScrollPhysics physics;
  final bool shrinkWrap;
  final EdgeInsetsGeometry padding;
  final double itemExtent;
  final int itemCount;
  final bool addAutomaticKeepAlives;
  final bool addRepaintBoundaries;
  final bool addSemanticIndexes;
  final double cacheExtent;
  final int semanticChildCount;

  /// Whether to show the overscroll glow on the side with negative scroll
  /// offsets.
  final bool showGlowLeading;

  /// Whether to show the overscroll glow on the side with positive scroll
  /// offsets.
  final bool showGlowTrailing;

  ListConfig(
    @required itemBuilder,
    @required sourceList, {
    this.showGlowLeading: true,
    this.showGlowTrailing: true,
    LoadingMoreIndicatorBuilder indicatorBuilder,
    SliverGridDelegate gridDelegate,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.controller,
    this.primary,
    this.physics,
    this.shrinkWrap = false,
    this.padding,
    this.itemExtent,
    this.itemCount,
    this.addAutomaticKeepAlives = true,
    this.addRepaintBoundaries = true,
    this.addSemanticIndexes = true,
    this.cacheExtent,
    this.semanticChildCount,
  }) : super(itemBuilder, sourceList,
            indicatorBuilder: indicatorBuilder, gridDelegate: gridDelegate);
}

create loading more ListView with following code:

 TuChongRepository listSourceRepository;
  @override
  void initState() {
    // TODO: implement initState
    listSourceRepository = new TuChongRepository();
    super.initState();
  }

  @override
  void dispose() {
    listSourceRepository?.dispose();
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: <Widget>[
          AppBar(
            title: Text("ListViewDemo"),
          ),
          Expanded(
            child: LoadingMoreList(
                ListConfig<TuChongItem>(
                    ItemBuilder.itemBuilder, listSourceRepository,
//                    showGlowLeading: false,
//                    showGlowTrailing: false,
                    padding: EdgeInsets.all(0.0)),),
          )
        ],
      ),
    );
  }

and it also support to loading error

3.loading more for Sliver or MultipleSlivers

SliverListConfig for SliverList/SliverGrid

//config for SliverList and SliverGrid
class SliverListConfig<T> extends LoadingMoreListConfig<T> {
  //whether show no more  .
  bool showNoMore = true;
  //whether show fullscreenLoading for multiple sliver
  bool showFullScreenLoading = true;

  final bool addAutomaticKeepAlives;
  final bool addRepaintBoundaries;
  final bool addSemanticIndexes;
  final SemanticIndexCallback semanticIndexCallback;
  final int semanticIndexOffset;
  final int childCount;

  SliverListConfig(
    @required itemBuilder,
    @required sourceList, {
    LoadingMoreIndicatorBuilder indicatorBuilder,
    SliverGridDelegate gridDelegate,
    this.addAutomaticKeepAlives = true,
    this.addRepaintBoundaries = true,
    this.addSemanticIndexes = true,
    this.semanticIndexCallback = _kDefaultSemanticIndexCallback,
    this.semanticIndexOffset = 0,
    this.childCount,
  }) : super(itemBuilder, sourceList,
            indicatorBuilder: indicatorBuilder, gridDelegate: gridDelegate);
}

create loading more SliverList with following code:

put Slivers into LoadingMoreCustomScrollView

 TuChongRepository listSourceRepository;
   @override
   void initState() {
     // TODO: implement initState
     listSourceRepository = new TuChongRepository();
     super.initState();
   }
 
   @override
   void dispose() {
     listSourceRepository?.dispose();
     // TODO: implement dispose
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
 
     return Material(
       child: LoadingMoreCustomScrollView(
         slivers: <Widget>[
           SliverAppBar(
             pinned: true,
             title: Text("SliverListDemo"),
           ),
           LoadingMoreSliverList(
               SliverListConfig<TuChongItem>(
                 ItemBuilder.itemBuilder, listSourceRepository,
                 //isLastOne: false
               ))
         ],
       ),
     );
   }

create loading more MultipleSlivers with following code:

and you can also use multiple sliver list.

 TuChongRepository listSourceRepository;
  TuChongRepository listSourceRepository1;

  @override
  void initState() {
    // TODO: implement initState
    listSourceRepository = new TuChongRepository();
    listSourceRepository1 = new TuChongRepository();
    super.initState();
  }

  @override
  void dispose() {
    listSourceRepository?.dispose();
    listSourceRepository1?.dispose();
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: LoadingMoreCustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            pinned: true,
            title: Text("MultipleSliverDemo"),
          ),
          LoadingMoreSliverList(SliverListConfig<TuChongItem>(
            ItemBuilder.itemBuilder,
            listSourceRepository,
          )),
          SliverToBoxAdapter(
            child: Container(
              alignment: Alignment.center,
              child: Text("Next list"),
              color: Colors.blue,
              height: 100.0,
            ),
          ),
          SliverPersistentHeader(
            delegate: CommonSliverPersistentHeaderDelegate(
                Container(
                  alignment: Alignment.center,
                  child: Text("Pinned Content"),
                  color: Colors.red,
                ),
                100.0),
            pinned: true,
          ),
          LoadingMoreSliverList(SliverListConfig<TuChongItem>(
            ItemBuilder.itemBuilder,
            listSourceRepository1,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              crossAxisSpacing: 3.0,
              mainAxisSpacing: 3.0,
//                    childAspectRatio: 0.5
            ),
          ))
        ],
      ),
    );
  }

4.loading more for CustomIndicator

provide indicatorBuilder and you can define your indicator base on loading status

 @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: <Widget>[
          AppBar(
            title: Text("CustomIndicatorDemo"),
          ),
          Expanded(
            child: LoadingMoreList(
              ListConfig<TuChongItem>(
                  ItemBuilder.itemBuilder, listSourceRepository,
                  indicatorBuilder: _buildIndicator,
                  padding: EdgeInsets.all(0.0),
              ),
            ),
          )
        ],
      ),
    );
  }

  //you can use IndicatorWidget or build yourself widget
  //in this demo, we define custom for all status.
  Widget _buildIndicator(BuildContext context, IndicatorStatus status) {
    Widget widget;
    bool full = (status == IndicatorStatus.FullScreenBusying);
    double height = 35.0;
    switch (status) {
      case IndicatorStatus.None:
        widget = Container(height: 0.0);
        height = 0.0;
        break;
      case IndicatorStatus.LoadingMoreBusying:
      case IndicatorStatus.FullScreenBusying:
        double indicatorSize = full ? 30.0 : 15.0;
        widget = Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
                margin: EdgeInsets.only(right: 15.0),
                height: indicatorSize,
                width: indicatorSize,
                child: getIndicator(context)),
            (!full
                ? Text(
                    "正在加载...慌什么慌",
                  )
                : Text("正在加载...慌什么慌",
                    style: TextStyle(
                        fontWeight: FontWeight.bold, fontSize: 28.0))),
          ],
        );
        break;
      case IndicatorStatus.Error:
        widget = Text(
          "加载失败,搞个川川",
        );
        break;
      case IndicatorStatus.NoMoreLoad:
        widget = Text("没有了,不要拖了");
        break;
      case IndicatorStatus.Empty:
        widget = EmptyWidget(
          "这里只有空",
        );
        break;
    }

    widget = Container(
        width: double.infinity,
        height: full ? double.infinity : height,
        child: widget,
        color: Colors.grey[200],
        alignment: Alignment.center);

//    if (isSliver) {
//      if (status == IndicatorStatus.FullScreenBusying) {
//        widget = SliverFillRemaining(
//          child: widget,
//        );
//      } else if (status == IndicatorStatus.Empty) {
//        widget = SliverToBoxAdapter(
//          child: widget,
//        );
//      }
//    }
    if (status == IndicatorStatus.Error) {
      widget = GestureDetector(
        onTap: () {
          listSourceRepository.loadMore();
        },
        child: widget,
      );
    }
    return widget;
  }

5.loading more for CustomIndicator

show how to use loading more list in NestedScrollView. in this demo, also support pull to refresh.

Tab0: This is a single sliver List with no pinned header Tab1: This is multiple loading sliver List with pinned header Tab2: This is a single ListView with pinned header

Please see the example app of this for a full example.

[0.1.5]

  • fix issue about full screen status in IndicatorWidget

[0.1.4]

  • make all loading_more_list darts as library loading_more_list

[0.1.3]

  • fix issue about IndicatorWidget.

[0.1.2]

  • Add FullScreenError status.
  • Fix issues for sliver list in NestedScrollView.
  • Add NestedScrollView demo for loading more list

[0.1.1]

  • Correct try again when it has error.

[0.1.0]

  • Upgrade Some Commments.

[0.0.1]

  • Initial Open Source release.

example/README.md

example

A new Flutter application.

Getting Started

For help getting started with Flutter, view our online documentation.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  loading_more_list: ^0.1.5

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:loading_more_list/loading_more_list.dart';
  
Version Uploaded Documentation Archive
0.1.5 Dec 11, 2018 Go to the documentation of loading_more_list 0.1.5 Download loading_more_list 0.1.5 archive
0.1.4 Dec 10, 2018 Go to the documentation of loading_more_list 0.1.4 Download loading_more_list 0.1.4 archive
0.1.2 Dec 9, 2018 Go to the documentation of loading_more_list 0.1.2 Download loading_more_list 0.1.2 archive
0.1.1 Dec 4, 2018 Go to the documentation of loading_more_list 0.1.1 Download loading_more_list 0.1.1 archive
0.1.0 Dec 3, 2018 Go to the documentation of loading_more_list 0.1.0 Download loading_more_list 0.1.0 archive
0.0.1 Dec 1, 2018 Go to the documentation of loading_more_list 0.0.1 Download loading_more_list 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
82
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
45
Learn more about scoring.

We analyzed this package on Dec 11, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0
  • pana: 0.12.7
  • Flutter: 1.0.0

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health issues and suggestions

Document public APIs (-9.02 points)

92 out of 102 API elements (library, class, field or method) have no adequate dartdoc content. Good documentation improves code readability and discoverability through search.

Fix lib/src/list_config.dart. (-4.89 points)

Analysis of lib/src/list_config.dart reported 10 hints, including:

line 35 col 5: The type parameter 'itemBuilder' is annotated with @required but only named parameters without default value can be annotated with it.

line 36 col 5: The type parameter 'sourceList' is annotated with @required but only named parameters without default value can be annotated with it.

line 122 col 5: The type parameter 'itemBuilder' is annotated with @required but only named parameters without default value can be annotated with it.

line 123 col 5: The type parameter 'sourceList' is annotated with @required but only named parameters without default value can be annotated with it.

line 224 col 25: The type parameter 'itemBuilder' is annotated with @required but only named parameters without default value can be annotated with it.

Fix lib/src/loading_more_sliver_list.dart. (-2.96 points)

Analysis of lib/src/loading_more_sliver_list.dart reported 6 hints, including:

line 23 col 7: This class inherits from a class marked as @immutable, and therefore should be immutable (all instance fields must be final).

line 81 col 10: The value of the local variable 'showFullScreenLoading' isn't used.

line 164 col 57: The member 'refresh' can only be used within instance members of subclasses of 'package:loading_more_list/src/loading_more_base.dart'.

line 165 col 57: The member 'loadMore' can only be used within instance members of subclasses of 'package:loading_more_list/src/loading_more_base.dart'.

line 169 col 55: The member 'refresh' can only be used within instance members of subclasses of 'package:loading_more_list/src/loading_more_base.dart'.

Fix lib/src/loading_more_list.dart. (-1 points)

Analysis of lib/src/loading_more_list.dart reported 2 hints:

line 34 col 38: The member 'refresh' can only be used within instance members of subclasses of 'package:loading_more_list/src/loading_more_base.dart'.

line 35 col 38: The member 'loadMore' can only be used within instance members of subclasses of 'package:loading_more_list/src/loading_more_base.dart'.

Fix lib/src/indicator_widget.dart. (-0.50 points)

Analysis of lib/src/indicator_widget.dart reported 1 hint:

line 7 col 7: This class inherits from a class marked as @immutable, and therefore should be immutable (all instance fields must be final).

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test