mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
RefreshIndicatorState.show() (#4877)
This commit is contained in:
parent
445f250c91
commit
12764a0066
@ -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> {
|
|||||||
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> {
|
|||||||
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> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
||||||
|
Loading…
Reference in New Issue
Block a user