diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 426b01a4fe..ec14c1c287 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -605,14 +605,18 @@ class ScaffoldState extends State with TickerProviderStateMixin { } /// Removes the current [SnackBar] by running its normal exit animation. + /// + /// The closed completer is called after the animation is complete. void hideCurrentSnackBar({ SnackBarClosedReason reason: SnackBarClosedReason.hide }) { assert(reason != null); if (_snackBars.isEmpty || _snackBarController.status == AnimationStatus.dismissed) return; final Completer completer = _snackBars.first._completer; - if (!completer.isCompleted) - completer.complete(reason); - _snackBarController.reverse(); + _snackBarController.reverse().then((Null _) { + assert(mounted); + if (!completer.isCompleted) + completer.complete(reason); + }); _snackBarTimer?.cancel(); _snackBarTimer = null; } diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart index 78ced10ca8..a050f06f7a 100644 --- a/packages/flutter/test/material/snack_bar_test.dart +++ b/packages/flutter/test/material/snack_bar_test.dart @@ -374,7 +374,11 @@ void main() { expect(actionPressed, isFalse); await tester.tap(find.text('ACTION')); expect(actionPressed, isTrue); - await tester.pump(const Duration(seconds: 1)); + // Closed reason is only set when the animation is complete. + await tester.pump(const Duration(milliseconds:250)); + expect(closedReason, isNull); + // Wait for animation to complete. + await tester.pumpAndSettle(const Duration(seconds: 1)); expect(closedReason, equals(SnackBarClosedReason.action)); // Pop up the snack bar and then swipe downwards to dismiss it. @@ -382,21 +386,21 @@ void main() { await tester.pump(const Duration(milliseconds: 750)); await tester.pump(const Duration(milliseconds: 750)); await tester.drag(find.text('snack'), const Offset(0.0, 50.0)); - await tester.pump(); + await tester.pumpAndSettle(const Duration(seconds: 1)); expect(closedReason, equals(SnackBarClosedReason.swipe)); // Pop up the snack bar and then remove it. await tester.tap(find.text('X')); await tester.pump(const Duration(milliseconds: 750)); scaffoldKey.currentState.removeCurrentSnackBar(); - await tester.pump(const Duration(seconds: 1)); + await tester.pumpAndSettle(const Duration(seconds: 1)); expect(closedReason, equals(SnackBarClosedReason.remove)); // Pop up the snack bar and then hide it. await tester.tap(find.text('X')); await tester.pump(const Duration(milliseconds: 750)); scaffoldKey.currentState.hideCurrentSnackBar(); - await tester.pump(const Duration(seconds: 1)); + await tester.pumpAndSettle(const Duration(seconds: 1)); expect(closedReason, equals(SnackBarClosedReason.hide)); // Pop up the snack bar and then let it time out. @@ -405,7 +409,7 @@ void main() { await tester.pump(const Duration(milliseconds: 750)); await tester.pump(const Duration(milliseconds: 1500)); await tester.pump(); // begin animation - await tester.pump(const Duration(milliseconds: 750)); + await tester.pumpAndSettle(const Duration(seconds: 1)); expect(closedReason, equals(SnackBarClosedReason.timeout)); });