Commit dd40d0e2 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Modal barrier shouldn't paint when the route is offstage. (#11347)

Fixes https://github.com/flutter/flutter/issues/11323
parent 8f56f6fd
......@@ -443,10 +443,10 @@ typedef bool RoutePredicate(Route<dynamic> route);
///
/// ### Popup routes
///
/// Routes don't have to obscure the entire screen. [PopupRoute]s cover
/// the screen with a barrierColor that can be only partially opaque to
/// allow the current screen to show through. Popup routes are "modal"
/// because they block input to the widgets below.
/// Routes don't have to obscure the entire screen. [PopupRoute]s cover the
/// screen with a [ModalRoute.barrierColor] that can be only partially opaque to
/// allow the current screen to show through. Popup routes are "modal" because
/// they block input to the widgets below.
///
/// There are functions which create and show popup routes. For
/// example: [showDialog], [showMenu], and [showModalBottomSheet]. These
......
......@@ -722,6 +722,9 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// The color to use for the modal barrier. If this is null, the barrier will
/// be transparent.
///
/// The color is ignored, and the barrier made invisible, when [offstage] is
/// true.
Color get barrierColor;
/// Whether the route should remain in memory when it is inactive. If this is
......@@ -741,6 +744,9 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// non-interactive, but each widget has its final size and position. This
/// mechanism lets the [HeroController] determine the final local of any hero
/// widgets being animated as part of the transition.
///
/// The modal barrier, if any, is not rendered if [offstage] is true (see
/// [barrierColor]).
bool get offstage => _offstage;
bool _offstage = false;
set offstage(bool value) {
......@@ -910,7 +916,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
// one of the builders
Widget _buildModalBarrier(BuildContext context) {
Widget barrier;
if (barrierColor != null) {
if (barrierColor != null && !offstage) {
assert(barrierColor != _kTransparent);
final Animation<Color> color = new ColorTween(
begin: _kTransparent,
......
......@@ -27,7 +27,7 @@ class TestTransition extends AnimatedWidget {
}
class TestRoute<T> extends PageRoute<T> {
TestRoute({ this.child, RouteSettings settings }) : super(settings: settings);
TestRoute({ this.child, RouteSettings settings, this.barrierColor }) : super(settings: settings);
final Widget child;
......@@ -35,7 +35,7 @@ class TestRoute<T> extends PageRoute<T> {
Duration get transitionDuration => const Duration(milliseconds: 150);
@override
Color get barrierColor => null;
final Color barrierColor;
@override
bool get maintainState => false;
......@@ -180,4 +180,31 @@ void main() {
expect(state(skipOffstage: false), equals('G')); // route 1 is not around any more
});
testWidgets('Check onstage/offstage handling of barriers around transitions', (WidgetTester tester) async {
await tester.pumpWidget(
new MaterialApp(
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/': return new TestRoute<Null>(settings: settings, child: const Text('A'));
case '/1': return new TestRoute<Null>(settings: settings, barrierColor: const Color(0xFFFFFF00), child: const Text('B'));
}
}
)
);
expect(find.byType(ModalBarrier), findsOneWidget);
tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/1');
expect(find.byType(ModalBarrier), findsOneWidget);
await tester.pump();
expect(find.byType(ModalBarrier), findsNWidgets(2));
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).first).color, isNull);
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, isNull);
await tester.pump(const Duration(seconds: 1));
expect(find.byType(ModalBarrier), findsOneWidget);
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier)).color, const Color(0xFFFFFF00));
});
}
......@@ -200,7 +200,7 @@ void main() {
expect(settingsOffset.dy, 100.0);
});
testWidgets('Check back gesture doesnt start during transitions', (WidgetTester tester) async {
testWidgets('Check back gesture doesn\'t start during transitions', (WidgetTester tester) async {
final GlobalKey containerKey1 = new GlobalKey();
final GlobalKey containerKey2 = new GlobalKey();
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
......
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