英雄小工具有效地在两个屏幕之间转换大小和位置。如何将其扩展为包括不透明度,以便在动画过程中有效地淡出一个屏幕的子屏幕,同时淡出第二个屏幕的个子屏幕。
我曾试图通过连接到ModalRoute.of(context(.animation和secondary animation的FadeTransitions来实现这一点,但它根本没有实现这一结果。相反,英雄每次出现时只有一个子角色可见。
第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),
),
),
),
第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),
),
),
),
我还希望能够在AnimatedBuilder中使用ModalRoute.of(context).animation
作为生成器的动画属性来转换Color
而不是不透明度,但遇到了同样的问题。
这包含在标准CupertinoPageRoute
中,但当使用材料Route
时,结果是相同的。
显然,这不是正确的做法。我想这是因为我错误地假设在转换过程中两个小部件都存在,但我对flightRouteBuilder
的尝试导致了几乎相同的结果。
你会怎么做。
更新##这在使用UserGestures进行转换时非常有效,但在通过Navigator.push()
或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),
),
我不能确定这是否是一个解决方案,但用它替换每个页面上的英雄已经奏效,并且在推送、弹出和用户手势方面都能正确操作。据我所见,Hero的默认flightShuttleBuilder将只渲染一个Widget,但保留两个Widget的Size和Positional参数。
要在每个屏幕上添加涉及Widget的额外转换,需要将两个Widget都放入flightShuttleBuilder中。然后有必要通过ModalRoute.of(context(访问路线转换的secondary Animation。secondary Animation.
为了创建我想要的FadTransition,from上下文和To上下文都放置在堆栈中。它们填充容器,因为它们自己的Widget将覆盖大小限制。然后,它们各自调用不同的FadeTransition,一个使用flightShuttleBuilder的动画,另一个使用ModalRoute.of(context).secondaryAnimation
。
#第1页
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(ModalRoute.of(context)?.secondaryAnimation ?? animation),
child: toHeroContext.widget)),
]);
},
child: Container(color: UIColor.blue, width: 100, height: 100),
);
#第2页
相同的接受英雄小工具的孩子是:
Container(color: UIColor.green, width: 120, height: 60),
编辑因此
目标是覆盖FlightShuttleBuilder以包含这两个小工具。这些小部件需要在一个堆栈中,每个小部件都用position.fill包装。然后可以像通常使用ModalRoute.of(context).animation
和ModalRoute.of(context).secondaryAnimation
一样设置动画。
例如:
Hero(
tag: 'test',
transitionOnUserGestures: true,
flightShuttleBuilder: (flightContext, animation, flightDirection, fromHeroContext, toHeroContext) {
return Stack(children: [
Positioned.fill(child: fromHeroContext.widget),
Positioned.fill(child: toHeroContext.widget),
]);
},
child: FadeTransition(
opacity: ModalRoute.of(context)?.animation ?? const AlwaysStoppedAnimation(1),
child: FadeTransition(
opacity: ReverseAnimation(ModalRoute.of(context)?.secondaryAnimation ?? const AlwaysStoppedAnimation(1)),
child: Container(color: UIColor.blue, width: 100, height: 100),
),
),
);