@@ -66,33 +66,46 @@ public Hero(
66
66
public readonly bool transitionOnUserGestures ;
67
67
68
68
internal static Dictionary < object , _HeroState >
69
- _allHeroesFor ( BuildContext context , bool isUserGestureTransition ) {
69
+ _allHeroesFor ( BuildContext context , bool isUserGestureTransition , NavigatorState navigator ) {
70
70
D . assert ( context != null ) ;
71
+ D . assert ( navigator != null ) ;
71
72
Dictionary < object , _HeroState > result = new Dictionary < object , _HeroState > { } ;
72
73
74
+ void addHero ( StatefulElement hero , object tag ) {
75
+ D . assert ( ( ) => {
76
+ if ( result . ContainsKey ( tag ) ) {
77
+ throw new UIWidgetsError (
78
+ "There are multiple heroes that share the same tag within a subtree.\n " +
79
+ "Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " +
80
+ "each Hero must have a unique non-null tag.\n " +
81
+ $ "In this case, multiple heroes had the following tag: { tag } \n " +
82
+ "Here is the subtree for one of the offending heroes:\n " +
83
+ $ "{ hero . toStringDeep ( prefixLineOne : "# " ) } "
84
+ ) ;
85
+ }
86
+
87
+ return true ;
88
+ } ) ;
89
+ _HeroState heroState = ( _HeroState ) hero . state ;
90
+ result [ tag ] = heroState ;
91
+ }
92
+
73
93
void visitor ( Element element ) {
74
94
if ( element . widget is Hero ) {
75
95
StatefulElement hero = ( StatefulElement ) element ;
76
96
Hero heroWidget = ( Hero ) element . widget ;
77
97
if ( ! isUserGestureTransition || heroWidget . transitionOnUserGestures ) {
78
98
object tag = heroWidget . tag ;
79
99
D . assert ( tag != null ) ;
80
- D . assert ( ( ) => {
81
- if ( result . ContainsKey ( tag ) ) {
82
- throw new UIWidgetsError (
83
- "There are multiple heroes that share the same tag within a subtree.\n " +
84
- "Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " +
85
- "each Hero must have a unique non-null tag.\n " +
86
- $ "In this case, multiple heroes had the following tag: { tag } \n " +
87
- "Here is the subtree for one of the offending heroes:\n " +
88
- $ "{ element . toStringDeep ( prefixLineOne : "# " ) } "
89
- ) ;
100
+ if ( Navigator . of ( hero ) == navigator ) {
101
+ addHero ( hero , tag ) ;
102
+ }
103
+ else {
104
+ ModalRoute heroRoute = ModalRoute . of ( hero ) ;
105
+ if ( heroRoute != null && heroRoute is PageRoute && heroRoute . isCurrent ) {
106
+ addHero ( hero , tag ) ;
90
107
}
91
-
92
- return true ;
93
- } ) ;
94
- _HeroState heroState = ( _HeroState ) hero . state ;
95
- result [ tag ] = heroState ;
108
+ }
96
109
}
97
110
}
98
111
@@ -131,6 +144,8 @@ public void endFlight() {
131
144
}
132
145
133
146
public override Widget build ( BuildContext context ) {
147
+ D . assert ( context . ancestorWidgetOfExactType ( typeof ( Hero ) ) == null ,
148
+ ( ) => "A Hero widget cannot be the descendant of another Hero widget." ) ;
134
149
if ( this . _placeholderSize != null ) {
135
150
if ( this . widget . placeholderBuilder == null ) {
136
151
return new SizedBox (
@@ -163,7 +178,7 @@ public _HeroFlightManifest(
163
178
HeroFlightShuttleBuilder shuttleBuilder ,
164
179
bool isUserGestureTransition
165
180
) {
166
- D . assert ( this . fromHero . widget . tag == this . toHero . widget . tag ) ;
181
+ D . assert ( fromHero . widget . tag == toHero . widget . tag ) ;
167
182
this . type = type ;
168
183
this . overlay = overlay ;
169
184
this . navigatorRect = navigatorRect ;
@@ -417,7 +432,7 @@ public override string ToString() {
417
432
}
418
433
419
434
public class HeroController : NavigatorObserver {
420
- HeroController ( CreateRectTween createRectTween ) {
435
+ public HeroController ( CreateRectTween createRectTween ) {
421
436
this . createRectTween = createRectTween ;
422
437
}
423
438
@@ -434,7 +449,16 @@ public override void didPush(Route route, Route previousRoute) {
434
449
public override void didPop ( Route route , Route previousRoute ) {
435
450
D . assert ( this . navigator != null ) ;
436
451
D . assert ( route != null ) ;
437
- this . _maybeStartHeroTransition ( route , previousRoute , HeroFlightDirection . pop , false ) ;
452
+ if ( ! this . navigator . userGestureInProgress ) {
453
+ this . _maybeStartHeroTransition ( route , previousRoute , HeroFlightDirection . pop , false ) ;
454
+ }
455
+ }
456
+
457
+ public override void didReplace ( Route newRoute = null , Route oldRoute = null ) {
458
+ D . assert ( this . navigator != null ) ;
459
+ if ( newRoute ? . isCurrent == true ) {
460
+ this . _maybeStartHeroTransition ( oldRoute , newRoute , HeroFlightDirection . push , false ) ;
461
+ }
438
462
}
439
463
440
464
public override void didStartUserGesture ( Route route , Route previousRoute ) {
@@ -496,14 +520,15 @@ bool isUserGestureTransition
496
520
497
521
Rect navigatorRect = HeroUtils . _globalBoundingBoxFor ( this . navigator . context ) ;
498
522
499
- Dictionary < object , _HeroState >
500
- fromHeroes = Hero . _allHeroesFor ( from . subtreeContext , isUserGestureTransition ) ;
501
- Dictionary < object , _HeroState > toHeroes = Hero . _allHeroesFor ( to . subtreeContext , isUserGestureTransition ) ;
523
+ Dictionary < object , _HeroState > fromHeroes =
524
+ Hero . _allHeroesFor ( from . subtreeContext , isUserGestureTransition , this . navigator ) ;
525
+ Dictionary < object , _HeroState > toHeroes =
526
+ Hero . _allHeroesFor ( to . subtreeContext , isUserGestureTransition , this . navigator ) ;
502
527
503
528
to . offstage = false ;
504
529
505
530
foreach ( object tag in fromHeroes . Keys ) {
506
- if ( toHeroes [ tag ] != null ) {
531
+ if ( toHeroes . ContainsKey ( tag ) ) {
507
532
HeroFlightShuttleBuilder fromShuttleBuilder = fromHeroes [ tag ] . widget . flightShuttleBuilder ;
508
533
HeroFlightShuttleBuilder toShuttleBuilder = toHeroes [ tag ] . widget . flightShuttleBuilder ;
509
534
@@ -521,16 +546,16 @@ bool isUserGestureTransition
521
546
isUserGestureTransition : isUserGestureTransition
522
547
) ;
523
548
524
- if ( this . _flights [ tag ] != null ) {
525
- this . _flights [ tag ] . divert ( manifest ) ;
549
+ if ( this . _flights . TryGetValue ( tag , out var result ) ) {
550
+ result . divert ( manifest ) ;
526
551
}
527
552
else {
528
553
this . _flights [ tag ] = new _HeroFlight ( this . _handleFlightEnded ) ;
529
554
this . _flights [ tag ] . start ( manifest ) ;
530
555
}
531
556
}
532
- else if ( this . _flights [ tag ] != null ) {
533
- this . _flights [ tag ] . abort ( ) ;
557
+ else if ( this . _flights . TryGetValue ( tag , out var result ) ) {
558
+ result . abort ( ) ;
534
559
}
535
560
}
536
561
}
0 commit comments