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 { ...@@ -18,6 +18,8 @@ class OverscrollDemo extends StatefulWidget {
} }
class OverscrollDemoState extends State<OverscrollDemo> { 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 GlobalKey<ScrollableState> _scrollableKey = new GlobalKey<ScrollableState>();
static final List<String> _items = <String>[ static final List<String> _items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N' 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'
...@@ -28,10 +30,19 @@ class OverscrollDemoState extends State<OverscrollDemo> { ...@@ -28,10 +30,19 @@ class OverscrollDemoState extends State<OverscrollDemo> {
Future<Null> refresh() { Future<Null> refresh() {
Completer<Null> completer = new Completer<Null>(); Completer<Null> completer = new Completer<Null>();
new Timer(new Duration(seconds: 3), () { completer.complete(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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String indicatorTypeText; String indicatorTypeText;
...@@ -68,6 +79,7 @@ class OverscrollDemoState extends State<OverscrollDemo> { ...@@ -68,6 +79,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
break; break;
case IndicatorType.refresh: case IndicatorType.refresh:
body = new RefreshIndicator( body = new RefreshIndicator(
key: _refreshIndicatorKey,
child: body, child: body,
refresh: refresh, refresh: refresh,
scrollableKey: _scrollableKey, scrollableKey: _scrollableKey,
...@@ -77,6 +89,7 @@ class OverscrollDemoState extends State<OverscrollDemo> { ...@@ -77,6 +89,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
} }
return new Scaffold( return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar( appBar: new AppBar(
title: new Text('$indicatorTypeText'), title: new Text('$indicatorTypeText'),
actions: <Widget>[ actions: <Widget>[
......
...@@ -121,10 +121,12 @@ class RefreshIndicator extends StatefulWidget { ...@@ -121,10 +121,12 @@ class RefreshIndicator extends StatefulWidget {
final RefreshIndicatorLocation location; final RefreshIndicatorLocation location;
@override @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 _sizeController = new AnimationController();
final AnimationController _scaleController = new AnimationController(); final AnimationController _scaleController = new AnimationController();
Animation<double> _sizeFactor; Animation<double> _sizeFactor;
...@@ -280,36 +282,56 @@ class _RefreshIndicatorState extends State<RefreshIndicator> { ...@@ -280,36 +282,56 @@ class _RefreshIndicatorState extends State<RefreshIndicator> {
} }
} }
Future<Null> _doHandlePointerUp(PointerUpEvent event) async { Future<Null> _show() async {
if (_mode == _RefreshIndicatorMode.armed) { _mode = _RefreshIndicatorMode.snap;
_mode = _RefreshIndicatorMode.snap; await _sizeController.animateTo(1.0 / _kDragSizeFactorLimit, duration: _kIndicatorSnapDuration);
await _sizeController.animateTo(1.0 / _kDragSizeFactorLimit, duration: _kIndicatorSnapDuration); if (mounted && _mode == _RefreshIndicatorMode.snap) {
if (mounted && _mode == _RefreshIndicatorMode.snap) { assert(config.refresh != null);
setState(() { setState(() {
_mode = _RefreshIndicatorMode.refresh; // Show the indeterminate progress indicator. _mode = _RefreshIndicatorMode.refresh; // Show the indeterminate progress indicator.
}); });
// Only one refresh callback is allowed to run at a time. If the user // 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 // attempts to start a refresh while one is still running ("pending") we
// just continue to wait on the pending refresh. // just continue to wait on the pending refresh.
if (_pendingRefreshFuture == null) if (_pendingRefreshFuture == null)
_pendingRefreshFuture = config.refresh(); _pendingRefreshFuture = config.refresh();
await _pendingRefreshFuture; await _pendingRefreshFuture;
bool completed = _pendingRefreshFuture != null; bool completed = _pendingRefreshFuture != null;
_pendingRefreshFuture = null; _pendingRefreshFuture = null;
if (mounted && completed && _mode == _RefreshIndicatorMode.refresh) if (mounted && completed && _mode == _RefreshIndicatorMode.refresh)
_dismiss(_DismissTransition.slide); _dismiss(_DismissTransition.slide);
}
} else if (_mode == _RefreshIndicatorMode.drag) {
_dismiss(_DismissTransition.shrink);
} }
} }
Future<Null> _doHandlePointerUp(PointerUpEvent event) async {
if (_mode == _RefreshIndicatorMode.armed)
_show();
else if (_mode == _RefreshIndicatorMode.drag)
_dismiss(_DismissTransition.shrink);
}
void _handlePointerUp(PointerEvent event) { void _handlePointerUp(PointerEvent event) {
_doHandlePointerUp(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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool showIndeterminateIndicator = 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