title: How to detect and run a loading function when scrolled to the bottom in customScrollView
body: <p>I am trying to run a load more when the user scrolls to the buttom of the list inside a customScrollView.</p>
  <p>I am doing a some sorting with sticky headers so had to use slivers with a <a href="https://pub.dev/packages/flutter_sticky_header" rel="nofollow noreferrer">flutter_sticky_header</a> package.</p>
  <p>this is the page code</p>
  <pre><code>class SoldEntryScreen extends StatelessWidget {
    const SoldEntryScreen({
      Key key,
      this.isDataLoading,
      this.isNextPageAvailable,
      this.transactions,
      this.loadNextPage,
      this.noError,
    });
  
    final bool isDataLoading;
    final bool isNextPageAvailable;
    final transactions;
    final Function loadNextPage;
    final bool noError;
  
    @override
    Widget build(BuildContext context) {
      var history = {};
  
      transactions.forEach((element) {
        final formatedDate = Utils.dateFormater(element.createdAt);
        if ((history[formatedDate['dateClass']] == null))
          return (history[formatedDate['dateClass']] = [element]);
        return history[formatedDate['dateClass']].add(element);
      });
      print(history);
      return AppScaffold(
        title: 'List Example',
        slivers: [
          SliverToBoxAdapter(
            child: SoldEntryPage(),
          ),
          _StickyHeaderDateSort(history: history),
        ],
      );
    }
  }
  
  class _StickyHeaderList extends StatelessWidget {
    const _StickyHeaderList({
      Key key,
      this.keyTitle,
      this.keyData,
    }) : super(key: key);
  
    final keyTitle;
    final keyData;
  
    @override
    Widget build(BuildContext context) {
      print(keyData);
      return SliverStickyHeader(
        header: Header(title: keyTitle),
        sliver: SliverToBoxAdapter(
          child: Container(
            child: ListView.separated(
              shrinkWrap: true,
              physics: ClampingScrollPhysics(),
            itemCount: keyData.length,
            itemBuilder: (context, index) {
              return MoneyTransactionModelListItem(
                              itemIndex: index, transaction: keyData[index]);
            },
            separatorBuilder: (BuildContext context, int index) =&gt;
                Divider(color: Theme.of(context).dividerColor),
          ),
          )
        ),
      );
    }
  }
  
  class _StickyHeaderDateSort extends StatelessWidget {
    const _StickyHeaderDateSort({
      Key key,
      this.history,
    }) : super(key: key);
  
    final history;
  
    @override
    Widget build(BuildContext context) {
      return SliverStickyHeader(
        header: HeaderDatePicker(),
        sliver: SliverToBoxAdapter(
          child: ShrinkWrappingViewport(
            offset: ViewportOffset.zero(),
            slivers: [
              for (var key in history.keys)
                _StickyHeaderList(keyTitle: key, keyData: history[key])
            ],
          ),
        ),
      );
    }
  }
  </code></pre>
  <p>which looks like something like this</p>
  <p><a href="https://i.stack.imgur.com/yWsXW.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yWsXW.gif" alt="enter image description here" /></a></p>
  <p>this is the <code>AppScaffold</code> widget</p>
  <pre><code>class AppScaffold extends StatelessWidget {
    const AppScaffold({
      Key key,
      @required this.title,
      @required this.slivers,
      this.reverse = false,
    }) : super(key: key);
  
    final String title;
    final List&lt;Widget&gt; slivers;
    final bool reverse;
  
    @override
    Widget build(BuildContext context) {
      return DefaultStickyHeaderController(
        child: CustomScrollView(
          slivers: slivers,
          reverse: reverse,
        ),
      );
    }
  }
  </code></pre>