|
3 | 3 | // found in the LICENSE file. |
4 | 4 |
|
5 | 5 | import 'package:flutter/foundation.dart'; |
6 | | - |
7 | 6 | import 'basic.dart'; |
8 | 7 | import 'binding.dart'; |
9 | 8 | import 'framework.dart'; |
| 9 | +import 'implicit_animations.dart'; |
| 10 | +import 'media_query.dart'; |
10 | 11 | import 'navigator.dart'; |
11 | 12 | import 'overlay.dart'; |
12 | 13 | import 'pages.dart'; |
@@ -135,9 +136,15 @@ enum HeroFlightDirection { |
135 | 136 | /// To make the animations look good, it's critical that the widget tree for the |
136 | 137 | /// hero in both locations be essentially identical. The widget of the *target* |
137 | 138 | /// is, by default, used to do the transition: when going from route A to route |
138 | | -/// B, route B's hero's widget is placed over route A's hero's widget. If a |
139 | | -/// [flightShuttleBuilder] is supplied, its output widget is shown during the |
140 | | -/// flight transition instead. |
| 139 | +/// B, route B's hero's widget is placed over route A's hero's widget. Additionally, |
| 140 | +/// if the [Hero] subtree changes appearance based on an [InheritedWidget] (such |
| 141 | +/// as [MediaQuery] or [Theme]), then the hero animation may have discontinuity |
| 142 | +/// at the start or the end of the animation because route A and route B provides |
| 143 | +/// different such [InheritedWidget]s. Consider providing a custom [flightShuttleBuilder] |
| 144 | +/// to ensure smooth transitions. The default [flightShuttleBuilder] interpolates |
| 145 | +/// [MediaQuery]'s paddings. If your [Hero] widget uses custom [InheritedWidget]s |
| 146 | +/// and displays a discontinuity in the animation, try to provide custom in-flight |
| 147 | +/// transition using [flightShuttleBuilder]. |
141 | 148 | /// |
142 | 149 | /// By default, both route A and route B's heroes are hidden while the |
143 | 150 | /// transitioning widget is animating in-flight above the 2 routes. |
@@ -910,8 +917,8 @@ class HeroController extends NavigatorObserver { |
910 | 917 | final NavigatorState? navigator = this.navigator; |
911 | 918 | final OverlayState? overlay = navigator?.overlay; |
912 | 919 | // If the navigator or the overlay was removed before this end-of-frame |
913 | | - // callback was called, then don't actually start a transition, and we don' |
914 | | - // t have to worry about any Hero widget we might have hidden in a previous |
| 920 | + // callback was called, then don't actually start a transition, and we don't |
| 921 | + // have to worry about any Hero widget we might have hidden in a previous |
915 | 922 | // flight, or ongoing flights. |
916 | 923 | if (navigator == null || overlay == null) { |
917 | 924 | return; |
@@ -998,7 +1005,35 @@ class HeroController extends NavigatorObserver { |
998 | 1005 | BuildContext toHeroContext, |
999 | 1006 | ) { |
1000 | 1007 | final Hero toHero = toHeroContext.widget as Hero; |
1001 | | - return toHero.child; |
| 1008 | + |
| 1009 | + final MediaQueryData? toMediaQueryData = MediaQuery.maybeOf(toHeroContext); |
| 1010 | + final MediaQueryData? fromMediaQueryData = MediaQuery.maybeOf(fromHeroContext); |
| 1011 | + |
| 1012 | + if (toMediaQueryData == null || fromMediaQueryData == null) { |
| 1013 | + return toHero.child; |
| 1014 | + } |
| 1015 | + |
| 1016 | + final EdgeInsets fromHeroPadding = fromMediaQueryData.padding; |
| 1017 | + final EdgeInsets toHeroPadding = toMediaQueryData.padding; |
| 1018 | + |
| 1019 | + return AnimatedBuilder( |
| 1020 | + animation: animation, |
| 1021 | + builder: (BuildContext context, Widget? child) { |
| 1022 | + return MediaQuery( |
| 1023 | + data: toMediaQueryData.copyWith( |
| 1024 | + padding: (flightDirection == HeroFlightDirection.push) |
| 1025 | + ? EdgeInsetsTween( |
| 1026 | + begin: fromHeroPadding, |
| 1027 | + end: toHeroPadding, |
| 1028 | + ).evaluate(animation) |
| 1029 | + : EdgeInsetsTween( |
| 1030 | + begin: toHeroPadding, |
| 1031 | + end: fromHeroPadding, |
| 1032 | + ).evaluate(animation), |
| 1033 | + ), |
| 1034 | + child: toHero.child); |
| 1035 | + }, |
| 1036 | + ); |
1002 | 1037 | } |
1003 | 1038 | } |
1004 | 1039 |
|
|
0 commit comments