The Hero Widget effectively transitions size and position between two screens. How would you extend it to include opacity so that it effectively fades out the child of one screen whilst fading in the child of the second screen during the animation.
I have tried to achieve this with FadeTransitions connected to the ModalRoute.of(context).animation and secondaryAnimation but it does not achieve this result at all. Instead only one child of each occurrence of the Hero is visible.
Page 1##
Hero(
tag: 'test',
transitionOnUserGestures: true,
child: FadeTransition(
opacity: Tween<double>(begin: 0, end: 1)
.animate(ModalRoute.of(context)?.animation ?? const AlwaysStoppedAnimation(1)),
child: FadeTransition(
opacity: Tween<double>(begin: 1, end: 0)
.animate(ModalRoute.of(context)?.secondaryAnimation ?? const AlwaysStoppedAnimation(1)),
child: Container(color: UIColor.blue, height: 100, width: 110),
),
),
),
Page 2##
Hero(
tag: 'test',
transitionOnUserGestures: true,
child: FadeTransition(
opacity: Tween<double>(begin: 0, end: 1)
.animate(ModalRoute.of(context)?.animation ?? const AlwaysStoppedAnimation(1)),
child: FadeTransition(
opacity: Tween<double>(begin: 1, end: 0)
.animate(ModalRoute.of(context)?.secondaryAnimation ?? const AlwaysStoppedAnimation(1)),
child: Container(color: UIColor.green, height: 60, width: 120),
),
),
),
I would further like to be able to transition the Color
instead of opacity in an AnimatedBuilder using the ModalRoute.of(context).animation
as the animation attribute of the builder, but have encountered the same problem.
This is contained in a standard CupertinoPageRoute
but the result is identical when using a Material Route
as well.
Clearly this is not the correct approach. I presume it is because I am falsely making an assumption that both widgets are present during the transition, but my attempt with the flightRouteBuilder
lead to almost identical results.
How would you go about this.
Update ##
This works perfectly when Transitioning with UserGestures, but does not when transitioning via Navigator.push()
or Navigator.pop()
:
Hero(
tag: 'test',
transitionOnUserGestures: true,
flightShuttleBuilder: (flightContext, animation, flightDirection, fromHeroContext, toHeroContext) {
return Stack(children: [
Positioned.fill(child: FadeTransition(opacity: animation, child: fromHeroContext.widget)),
Positioned.fill(child: FadeTransition(opacity: ReverseAnimation(animation), child: toHeroContext.widget)),
]);
},
child: Container(color: UIColor.green, width: 120, height: 60),
),