前言
继续 Hero
组件的介绍,本篇来介绍 Hero
组件的另一个属性 flightShuttleBuilder
。这个属性用于设置飞行过程中的组件。默认的话 Hero
组件在飞行过程中是使用源页面的 Hero
子组件。有了flightShuttleBuilder
,我们就可以在行过程中可以更换组件。
flightShuttleBuilder 定义
flightShuttleBuilder
是一个返回飞行过程中的方法,定义如下:
typedef HeroFlightShuttleBuilder = Widget Function(
BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext,
);
其中 flightDirection
是一个枚举,用于区分是 push
还是 pop
。animation
原以为会在动画过程中变化,但是 debug
的时候发现只有一个起始值。三个 context
是在需要的时候可以使用,一般用不到。我们可以通过flightDirection
来定义 push
过程和 pop
过程中的组件。
示例
示例起始比较简单,我们这里使用了两个简单的色块作为飞行中的组件。
flightShuttleBuilder: (_, animation, direction, __, ___) {
if (direction == HeroFlightDirection.push) {
return ClipOval(
child: Opacity(
child: Container(color: Colors.pink),
opacity: 0.4,
),
);
} else {
return ClipOval(
child: Opacity(
child: Container(color: Colors.blue),
opacity: 0.4,
),
);
}
},
注意,这个只需要在源页面的 Hero 组件定义就可以了,无需在目标 Hero 组件定义。下面是运行效果。从目前的使用来看,感觉好处是如果前后两个 Hero 的组件存在差别,使用来回不同的飞行组件可能会感觉更一致一些。其他似乎并没有很大的用途,可能还需要继续深入研究应用案例。
飞行组件替换.gif
平台差异性
注意Hero 组件在 iOS 和安卓平台是有差异的,最大的差异是 iOS 的兼容性有点问题,比如 iOS 在模拟器上需要开启 transitionOnUserGestures
为 true
才支持返回。
如果不开启,点击几次导航栏的返回按钮后会报错:'_backGestureController != null': is not true
。网上是说模拟器的问题,真机还没验证。而开启后,虽然不会报错,但是点击目标页面的 Hero 组件不会返回源页面。点击返回按钮或用手势倒没什么问题。安卓平台是没有这个问题的。
这个问题需要区分平台处理,对于 iOS 平台开启因此,iOS 平台需要特别注意一下。解决的方法之一是,在 iOS平台上设置 MaterialPageRoute
的fullscreenDialog
属性为 true
。不过这样是不支持侧滑返回了。如下所示:
Navigator.of(context).push(
MaterialPageRoute(
fullscreenDialog: true,
//...
)
)
因此,在 iOS 平台,如果 Hero 组件有点击互动的效果的,推荐设置fullscreenDialog
为 true
。如果没有是可以设置transitionOnUserGestures
为 true
来支持手势操作。
总结
本篇介绍了 Hero
组件的flightShuttleBuilder
的使用,以及 iOS 和安卓平台在Hero 组件的差异化处理。那么 Hero
组件到底有哪些应用场景呢,接下来我会讲两个应用案例。相关源码已上传至:Flutter 入门与实战 - 动画相关源码。
网友评论