Commit 12764a00 authored by Hans Muller's avatar Hans Muller Committed by GitHub

RefreshIndicatorState.show() (#4877)

parent 445f250c
......@@ -18,6 +18,8 @@ class OverscrollDemo extends StatefulWidget {
}
class OverscrollDemoState extends State<OverscrollDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = new GlobalKey<RefreshIndicatorState>();
static final GlobalKey<ScrollableState> _scrollableKey = new GlobalKey<ScrollableState>();
static final List<String> _items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'
......@@ -28,10 +30,19 @@ class OverscrollDemoState extends State<OverscrollDemo> {
Future<Null> refresh() {
Completer<Null> completer = new Completer<Null>();
new Timer(new Duration(seconds: 3), () { completer.complete(null); });
return completer.future;
return completer.future.then((_) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text("Refresh complete"),
action: new SnackBarAction(
label: 'RETRY',
onPressed: () {
_refreshIndicatorKey.currentState.show();
}
)
));
});
}
@override
Widget build(BuildContext context) {
String indicatorTypeText;
......@@ -68,6 +79,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
break;
case IndicatorType.refresh:
body = new RefreshIndicator(
key: _refreshIndicatorKey,
child: body,
refresh: refresh,
scrollableKey: _scrollableKey,
......@@ -77,6 +89,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
}
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('$indicatorTypeText'),
actions: <Widget>[
......
......@@ -121,10 +121,12 @@ class RefreshIndicator extends StatefulWidget {
final RefreshIndicatorLocation location;
@override
_RefreshIndicatorState createState() => new _RefreshIndicatorState();
RefreshIndicatorState createState() => new RefreshIndicatorState();
}
class _RefreshIndicatorState extends State<RefreshIndicator> {
/// Contains the state for a [RefreshIndicator]. This class can be used to
/// programmatically show the refresh indicator, see the [show] method.
class RefreshIndicatorState extends State<RefreshIndicator> {
final AnimationController _sizeController = new AnimationController();
final AnimationController _scaleController = new AnimationController();
Animation<double> _sizeFactor;
......@@ -280,36 +282,56 @@ class _RefreshIndicatorState extends State<RefreshIndicator> {
}
}
Future<Null> _doHandlePointerUp(PointerUpEvent event) async {
if (_mode == _RefreshIndicatorMode.armed) {
_mode = _RefreshIndicatorMode.snap;
await _sizeController.animateTo(1.0 / _kDragSizeFactorLimit, duration: _kIndicatorSnapDuration);
if (mounted && _mode == _RefreshIndicatorMode.snap) {
setState(() {
_mode = _RefreshIndicatorMode.refresh; // Show the indeterminate progress indicator.
});
Future<Null> _show() async {
_mode = _RefreshIndicatorMode.snap;
await _sizeController.animateTo(1.0 / _kDragSizeFactorLimit, duration: _kIndicatorSnapDuration);
if (mounted && _mode == _RefreshIndicatorMode.snap) {
assert(config.refresh != null);
setState(() {
_mode = _RefreshIndicatorMode.refresh; // Show the indeterminate progress indicator.
});
// Only one refresh callback is allowed to run at a time. If the user
// attempts to start a refresh while one is still running ("pending") we
// just continue to wait on the pending refresh.
if (_pendingRefreshFuture == null)
_pendingRefreshFuture = config.refresh();
await _pendingRefreshFuture;
bool completed = _pendingRefreshFuture != null;
_pendingRefreshFuture = null;
if (mounted && completed && _mode == _RefreshIndicatorMode.refresh)
_dismiss(_DismissTransition.slide);
}
} else if (_mode == _RefreshIndicatorMode.drag) {
_dismiss(_DismissTransition.shrink);
// Only one refresh callback is allowed to run at a time. If the user
// attempts to start a refresh while one is still running ("pending") we
// just continue to wait on the pending refresh.
if (_pendingRefreshFuture == null)
_pendingRefreshFuture = config.refresh();
await _pendingRefreshFuture;
bool completed = _pendingRefreshFuture != null;
_pendingRefreshFuture = null;
if (mounted && completed && _mode == _RefreshIndicatorMode.refresh)
_dismiss(_DismissTransition.slide);
}
}
Future<Null> _doHandlePointerUp(PointerUpEvent event) async {
if (_mode == _RefreshIndicatorMode.armed)
_show();
else if (_mode == _RefreshIndicatorMode.drag)
_dismiss(_DismissTransition.shrink);
}
void _handlePointerUp(PointerEvent event) {
_doHandlePointerUp(event);
}
/// Show the refresh indicator and run the refresh callback as if it had
/// been started interactively. If this method is called while the refresh
/// callback is running, it quietly does nothing.
///
/// See also:
///
/// * [GlobalKey] (creating the RefreshIndicator with a [GlobalKey<RefreshIndicatorState>]
/// will make it possible to refer to the [RefreshIndicatorState] later)
Future<Null> show() async {
if (_mode != _RefreshIndicatorMode.refresh) {
_sizeController.value = 0.0;
_scaleController.value = 0.0;
await _show();
}
}
@override
Widget build(BuildContext context) {
final bool showIndeterminateIndicator =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment