Refresher

My custom Pull to Refresh Widget, mimicking iOS Pull to Refresh except for the toolbar

Installation

First, add refresher as a dependency in your pubspec.yaml file.

refresher: ^0.0.4+2

Example

class RefresherDemo extends StatefulWidget {
  @override
  _RefresherDemoState createState() => _RefresherDemoState();
}

class _RefresherDemoState extends State<RefresherDemo> with SingleTickerProviderStateMixin {
  String _title = "Refresher Demo";

  double percentage = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(_title), actions: [
        IconButton(
          icon: Icon(Icons.navigate_next),
          onPressed: () {
            Navigator.push(context,
                MaterialPageRoute(builder: (BuildContext context) => InfiniteRefresherDemo()));
          },
        )
      ]),
      body: Refresher(
          loadingSize: 50.0,
          margin: EdgeInsets.all(8.0),
          onRefresh: () async {
            int counter = 0;
            Timer.periodic(Duration(milliseconds: 1000), (t) {
              counter++;
              if (this.mounted)
                setState(() {
                  _title = "Fetching${List.filled(counter, ".").join()}";
                  if (counter == 5) t.cancel();
                });
            });
            await Future.delayed(new Duration(milliseconds: 6000));
            if (this.mounted)
              setState(() {
                _title = "Refresher Demo";
              });
          },
          child: Column(
              children: List.generate(
            100,
            (index) => Text("Here is $index"),
          ))),
    );
  }
}

Infinite Example

class InfiniteRefresherDemo extends StatefulWidget {
  @override
  _InfiniteRefresherDemoState createState() => _InfiniteRefresherDemoState();
}

class _InfiniteRefresherDemoState extends State<InfiniteRefresherDemo>
    with SingleTickerProviderStateMixin {
  String _title = "Infinite Refresher Demo";
  List<Widget> _children = [];
  double percentage = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(_title),
      ),
      body: InfiniteRefresher(
        loadingSize: 50.0,
        margin: EdgeInsets.all(8.0),
        onRefresh: () async {
          int counter = 0;
          Timer.periodic(Duration(milliseconds: 1000), (t) {
            counter++;
            if (this.mounted)
              setState(() {
                _title = "Fetching${List.filled(counter, ".").join()}";
                if (counter == 5) t.cancel();
              });
          });
          await Future.delayed(new Duration(milliseconds: 1000));
          _children.clear();
          _children.addAll(List.generate(
            Random().nextInt(100),
                (index) => Text("Here is $index"),
          ));
          if (this.mounted)
            setState(() {
              _title = "Infinite Refresher Demo";
            });
        },
        widgetBuilder: (context) {
          return Column(children: _children);
        },
        fetcher: (context, cursor) async {
          await Future.delayed(Duration(milliseconds: 3000));

          _children.addAll(List.generate(
            Random().nextInt(100),
            (index) => Text("Here is $index"),
          ));

          return true;
        },
      ),
    );
  }
}

Libraries

always_bouncing_physics
infinite_list_view
loading_animation
not_bouncing_physics
refresh_indicator_physics
refresher
refresher_infinite

Dart

VM

dart:ffi
Foreign Function Interface for interoperability with the C programming language. [...]

Web

dart:html
HTML elements and other resources for web-based applications that need to interact with the browser and the DOM (Document Object Model). [...]
dart:js
Low-level support for interoperating with JavaScript. [...]
dart:js_util
Utility methods to efficiently manipulate typed JSInterop objects in cases where the name to call is not known at runtime. You should only use these methods when the same effect cannot be achieved with @JS annotations. These methods would be extension methods on JSObject if Dart supported extension methods.