Modal barrier shouldn't paint when the route is offstage. (#11347)
Fixes https://github.com/flutter/flutter/issues/11323
This commit is contained in:
parent
8f56f6fdd1
commit
dd40d0e29c
@ -443,10 +443,10 @@ typedef bool RoutePredicate(Route<dynamic> route);
|
|||||||
///
|
///
|
||||||
/// ### Popup routes
|
/// ### Popup routes
|
||||||
///
|
///
|
||||||
/// Routes don't have to obscure the entire screen. [PopupRoute]s cover
|
/// Routes don't have to obscure the entire screen. [PopupRoute]s cover the
|
||||||
/// the screen with a barrierColor that can be only partially opaque to
|
/// screen with a [ModalRoute.barrierColor] that can be only partially opaque to
|
||||||
/// allow the current screen to show through. Popup routes are "modal"
|
/// allow the current screen to show through. Popup routes are "modal" because
|
||||||
/// because they block input to the widgets below.
|
/// they block input to the widgets below.
|
||||||
///
|
///
|
||||||
/// There are functions which create and show popup routes. For
|
/// There are functions which create and show popup routes. For
|
||||||
/// example: [showDialog], [showMenu], and [showModalBottomSheet]. These
|
/// 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
|
/// The color to use for the modal barrier. If this is null, the barrier will
|
||||||
/// be transparent.
|
/// be transparent.
|
||||||
|
///
|
||||||
|
/// The color is ignored, and the barrier made invisible, when [offstage] is
|
||||||
|
/// true.
|
||||||
Color get barrierColor;
|
Color get barrierColor;
|
||||||
|
|
||||||
/// Whether the route should remain in memory when it is inactive. If this is
|
/// 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
|
/// non-interactive, but each widget has its final size and position. This
|
||||||
/// mechanism lets the [HeroController] determine the final local of any hero
|
/// mechanism lets the [HeroController] determine the final local of any hero
|
||||||
/// widgets being animated as part of the transition.
|
/// 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 get offstage => _offstage;
|
||||||
bool _offstage = false;
|
bool _offstage = false;
|
||||||
set offstage(bool value) {
|
set offstage(bool value) {
|
||||||
@ -910,7 +916,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
|
|||||||
// one of the builders
|
// one of the builders
|
||||||
Widget _buildModalBarrier(BuildContext context) {
|
Widget _buildModalBarrier(BuildContext context) {
|
||||||
Widget barrier;
|
Widget barrier;
|
||||||
if (barrierColor != null) {
|
if (barrierColor != null && !offstage) {
|
||||||
assert(barrierColor != _kTransparent);
|
assert(barrierColor != _kTransparent);
|
||||||
final Animation<Color> color = new ColorTween(
|
final Animation<Color> color = new ColorTween(
|
||||||
begin: _kTransparent,
|
begin: _kTransparent,
|
||||||
|
@ -27,7 +27,7 @@ class TestTransition extends AnimatedWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TestRoute<T> extends PageRoute<T> {
|
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;
|
final Widget child;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class TestRoute<T> extends PageRoute<T> {
|
|||||||
Duration get transitionDuration => const Duration(milliseconds: 150);
|
Duration get transitionDuration => const Duration(milliseconds: 150);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get barrierColor => null;
|
final Color barrierColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get maintainState => false;
|
bool get maintainState => false;
|
||||||
@ -180,4 +180,31 @@ void main() {
|
|||||||
expect(state(skipOffstage: false), equals('G')); // route 1 is not around any more
|
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);
|
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 containerKey1 = new GlobalKey();
|
||||||
final GlobalKey containerKey2 = new GlobalKey();
|
final GlobalKey containerKey2 = new GlobalKey();
|
||||||
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user