如何使用Flutter中的英雄过渡期间未运行的动画/动画?

时间:2019-02-01 01:49:36

标签: animation dart flutter widget

我有一张描述产品的卡片网格。轻按卡片时,我希望它翻转(绕Y轴)以显示显示详细信息的“另一面”,同时又增长以填充屏幕。

  • 持续时间0.0-卡片显示正面并且处于网格视图
  • 持续时间0.5-卡是全屏显示方式的50%,并且垂直于屏幕(正面朝右,“背面”朝左)
  • 持续时间1.0-记忆卡已完全展开,并且显示“背面”卡片。

我设法使翻转动画起作用,但是在弄清楚如何获得它以使其在Hero过渡期间运行时遇到困难。从this article看来,我可能需要利用flightShuttleBuilder来使叠加层动起来,但是动画在过渡期间无法运行:

return Hero(
  tag: 'test',
  flightShuttleBuilder: (
    BuildContext flightContext,
    Animation<double> animation,
    HeroFlightDirection flightDirection,
    BuildContext fromHeroContext,
    BuildContext toHeroContext,
  ) {
    final Hero toHero = toHeroContext.widget;
    return Transform(
      transform: Matrix4.identity()..rotateY(-pi * animation.value),
      alignment: FractionalOffset.center,
      child: toHero,
    );
  },
  child: Card(...),
);

2 个答案:

答案 0 :(得分:0)

事实证明,flightShuttleBuilder仅在过渡的开始和结束时发出值,而不是在整个动画中发出值。从this issue on GitHub捕获,这显然是预期的行为。

解决方法是创建您自己的过渡,该过渡从AnimatedWidget开始;会正常发出值,并且可以在flightShuttleBuilder中使用:

class FlipcardTransition extends AnimatedWidget {
  final Animation<double> flipAnim;
  final Widget child;

  FlipcardTransition({@required this.flipAnim, @required this.child})
      : assert(flipAnim != null),
        assert(child != null),
        super(listenable: flipAnim);

  @override
  Widget build(BuildContext context) {
    return Transform(
      transform: Matrix4.identity()
        ..rotateY(-pi * flipAnim.value),
      alignment: FractionalOffset.center,
      child: child,
    );
  }
}

...

flightShuttleBuilder: (BuildContext flightContext,
  Animation<double> animation,
  HeroFlightDirection flightDirection,
  BuildContext fromHeroContext,
  BuildContext toHeroContext,) {
    final Hero toHero = toHeroContext.widget;
    return FlipcardTransition(
      flipAnim: animation,
      child: toHero,
    );
},

答案 1 :(得分:0)

正如Matt所说,默认行为只是发出起始值和结束值,因此我们应该收听动画以获取完整的可动画制作的小部件。这是一个示例:

Hero(
  tag: "YourHeroTag",
  flightShuttleBuilder: (BuildContext flightContext,
    Animation<double> animation,
    HeroFlightDirection flightDirection,
    BuildContext fromHeroContext,
    BuildContext toHeroContext,) {
      return AnimatedBuilder(
        animation: animation,
        builder: (context, value) {
          return Container(
            color: Color.lerp(Colors.white, Colors.black87, animation.value),
          );
        },
      );
  },
  child: Material( // Wrap in Material to prevent missing theme, mediaquery, ... features....
    // ...
  )
)

建议包装Material小部件以防止样式意外丢失。