Flutter圈子Flutter 入门与实战

如何更改 Hero 组件的飞行过程的子组件?

2022-06-12  本文已影响0人  岛上码农

前言

继续 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 还是 popanimation 原以为会在动画过程中变化,但是 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 在模拟器上需要开启 transitionOnUserGesturestrue 才支持返回。

如果不开启,点击几次导航栏的返回按钮后会报错:'_backGestureController != null': is not true。网上是说模拟器的问题,真机还没验证。而开启后,虽然不会报错,但是点击目标页面的 Hero 组件不会返回源页面。点击返回按钮或用手势倒没什么问题。安卓平台是没有这个问题的。

这个问题需要区分平台处理,对于 iOS 平台开启因此,iOS 平台需要特别注意一下。解决的方法之一是,在 iOS平台上设置 MaterialPageRoutefullscreenDialog 属性为 true。不过这样是不支持侧滑返回了。如下所示:

Navigator.of(context).push(
  MaterialPageRoute(
    fullscreenDialog: true,
    //...
 )
)

因此,在 iOS 平台,如果 Hero 组件有点击互动的效果的,推荐设置fullscreenDialogtrue。如果没有是可以设置transitionOnUserGesturestrue 来支持手势操作。

总结

本篇介绍了 Hero 组件的flightShuttleBuilder的使用,以及 iOS 和安卓平台在Hero 组件的差异化处理。那么 Hero 组件到底有哪些应用场景呢,接下来我会讲两个应用案例。相关源码已上传至:Flutter 入门与实战 - 动画相关源码

上一篇下一篇

猜你喜欢

热点阅读