|
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