长笛英雄动画转换不透明度和/或颜色



英雄小工具有效地在两个屏幕之间转换大小和位置。如何将其扩展为包括不透明度,以便在动画过程中有效地淡出一个屏幕的子屏幕,同时淡出第二个屏幕的个子屏幕。

我曾试图通过连接到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).animationModalRoute.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),
),
),
);

最新更新