Flutter 动画组件

1、AnimatedContainer

在一段时间内逐渐改变属性值的 Container

null 的属性,以及 Container 的子孙不会发生动画。

AnimatedContainer 使用内部的 AnimationController,在 Container 的属性中产生简单的、隐式动画。

如果要产生更复杂的动画,可以使用 AnimatedWidget 的子类(例如 DecoratedBoxTransition),或者自己声明的 AnimationController

演示视频

2、AnimatedCrossFade

widget 的两个 children 之间交叉淡入淡出,并在 children 的尺寸之间产生动画。

通过 crossFadeState 参数控制动画。firstCurvesecondCurve 表示两个 children 的不透明曲线。sizeCurve 表示在淡出 child 的尺寸和淡入 child 尺寸之间的动画曲线。

AnimatedCrossFade 用于淡入淡出一对相同宽度的 widgets。如果两个 children 的高度不同,动画会对其 children 的顶部边缘,并裁剪溢出的部分,也就是会裁剪底部。

使用不同的 crossFadeState 属性值重建 AnimatedCrossFade 时,将自动触发动画。

AnimatedCrossFade(
  duration: const Duration(seconds: 3),
  firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
  secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
  crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)
复制代码

3、Hero

标记 widgetchildhero animations 的候选人。

Hero animation: 使用 Navigator 压入或弹出 PageRoute时,会替换整个屏幕的内容。如果两个路由有共同的视觉特征,那么在路由过渡期间,可以告诉用户该特征从一个页面移动了另一个页面。过渡期间,hero widgetNavigator 层之上“飞行”。默认情况下,飞行期间不会在旧路由和新路由上显示原来的位置。

发生导航时,每个路由的 Hero widgetsHeroController 确定。有相同 tag 的每一对 Hero widgets 都会触发 Hero animation

一个路由不能包含多个相同 tagHero

4、AnimatedBuilder

创建动画的通用 widget

AnimatedBuilder 适用于在复杂的 build 函数中包含动画的 widgets

对于没有额外状态的简单情况,考虑使用 AnimatedWidget

class Spinner extends StatefulWidget {
  @override
  _SpinnerState createState() => _SpinnerState();
}

class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 10),
      vsync: this,
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      child: Container(width: 200.0, height: 200.0, color: Colors.green),
      builder: (BuildContext context, Widget child) {
        return Transform.rotate(
          angle: _controller.value * 2.0 * math.pi,
          child: child,
        );
      },
    );
  }
}
复制代码

5、DecoratedBoxTransition

DecoratedBox 的动画版,让 Decoration 的不同属性产生动画。

演示视频

6、FadeTransition

使 widget 的不透明度产生动画。

参考:2、AnimatedCrossFade

演示视频

7、PositionedTransition

Positioned 的动画版,使用指定的 Animation<RelativeRect>,在动画的生命周期里,把 child 的位置从起点过渡到终点。

只有是 Stackchild 时才能工作。

演示视频

8、RotationTransition

使 widget 的选择产生动画。

演示视频

9、ScaleTransition

使 widget 的缩放产生动画。

演示视频

10、SizeTransition

使自身的尺寸产生动画,并裁剪和对其它的 child

SizeTransition 类似 ClipRect,根据 axis 的值,使它的宽度或高度产生动画。

演示视频

11、SlideTransition

相对于 widget 的正常位置,让它的位置产生动画。

通过 Offset 相对于 child 的尺寸产生动画。例如,Offsetdx 值是 0.25,则会产生 child 四分之一宽度的水平位置动画。

演示视频

12、AnimatedDefaultTextStyle

DefaultTextStyle 的动画版。当给定的样式改变时,在给定的周期内产生动画。

textAlignsoftWraptextOverflowmaxLines 属性不会产生动画,改变时立即生效。

演示视频

13、AnimatedListState

在可滚动容器中 state的插入或移除项时产生动画。

14、AnimatedModalBarrier

阻止用户与 widget 后面的 widgets 交互,可以配置一个有动画的颜色值。

ModalBarrier 类似,AnimatedModalBarrier 接收一个有动画的 color,而不是单个颜色。

15、AnimatedOpacity

Opacity 的动画版,当给定的不透明度变化时,在给定周期内过渡 child 的不透明度。

这个动画很昂贵,因为需要把 child 绘制到一个中间缓存中。

演示视频

class LogoFade extends StatefulWidget {
  @override
  createState() => LogoFadeState();
}

class LogoFadeState extends State<LogoFade> {
  double opacityLevel = 1.0;

  void _changeOpacity() {
    setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        AnimatedOpacity(
          opacity: opacityLevel,
          duration: Duration(seconds: 3),
          child: FlutterLogo(),
        ),
        RaisedButton(
          child: Text('Fade Logo'),
          onPressed: _changeOpacity,
        ),
      ],
    );
  }
}
复制代码

参考:6、FadeTransition,该 widget 的明确版,由调用者传入 Animation,而不是使用内置的。

16、AnimatedPhysicalModel

PhysicalModel 的动画版,borderRadiuselevation 会产生动画,shap 不会产生动画。

如果设置了 animateColor 属性,则 color 也会产生动画;否则会颜色会立即改变。这可以让颜色单独产生动画(比如由 AnimatedTheme 驱动)。

演示视频

17、AnimatedPositioned

Positioned 的动画版。

只有是 Stackchild 时才能工作。

如果 childsize 在动画过程会改变,则 AnimatedPositioned 是很好的选择。如果尺寸不变,只有 position 改变,则考虑使用 SlideTransition

演示视频

18、AnimatedSize

动画改变 child 尺寸的 widget

19、AnimatedWidget

当给定的 Listenable 的值改变时,AnimatedWidgetrebuild

AnimatedWidget 最常见的用法是与 Animation 对象配合,AnimationListenable。但它也可以与任何 Listenable 配置,包括 ChangeNotifierValueNotifier

AnimatedWidget 对无状态的 widget 最有用。只需要继承 AnimatedWidget,并实现 build 函数。

class Spinner extends StatefulWidget {
  @override
  _SpinnerState createState() => _SpinnerState();
}

class _SpinnerState extends State<Spinner> with TickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 10),
      vsync: this,
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SpinningContainer(controller: _controller);
  }
}

class SpinningContainer extends AnimatedWidget {
  const SpinningContainer({Key key, AnimationController controller})
      : super(key: key, listenable: controller);

  Animation<double> get _progress => listenable;

  @override
  Widget build(BuildContext context) {
    return Transform.rotate(
      angle: _progress.value * 2.0 * math.pi,
      child: Container(width: 200.0, height: 200.0, color: Colors.green),
    );
  }
}
复制代码

20、AnimatedWidgetBaseState

具有隐式动画的 widget 的基类,需要在动画执行时 rebuild widget tree

转载于:https://juejin.im/post/5cd29423518825356a1add06

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值