TreeviewCopyright © aleen42 all right reserved, powered by aleen42

简介

回想一下 Android 的属性动画,我们经常使用的是 ValueAnimator.ofXXX 方法,指定一个起始值,再设定一个耗时,然后系统会根据插值器计算出这段时间内各个时间点内的值。

Flutter 其实也大致一样,AnimationController 默认情况下,会在一个时间段内,线性的生成 0.0~1.0 的数字,也就是说,AnimationController 可以单独的完成一些简单的、数值类的动画效果,如下图:

12123

构造函数

看一下它的构造函数:

  AnimationController({
    double value,    
    this.duration,
    this.reverseDuration,
    this.debugLabel,
    this.lowerBound = 0.0,
    this.upperBound = 1.0,
    this.animationBehavior = AnimationBehavior.normal,
    @required TickerProvider vsync,
  })
  • view,动画的值,该值会随着动画的进度而发生变化
  • duration,动画持续时间
  • reverseDuration,反向动画的持续时间,如果不设置该值,则反向动画持续时间和正向一样
  • debugLabel,可以为动画设置一个标签,调用 AnimationControllertoString() 方法可以输出该标签,用于调试动画时使用
  • lowerBound,动画的起始值,默认为 0.0
  • upperBound,动画的结束值,默认为 1.0

需要注意,当我们自定义 lowerBoundupperBound 时,upperBound 必须大于 lowerBound,你想要从大变小,将 upperBound 设置小于(或者等于)lowerBound 是不可以的。

了解了这些,创建一个 AnimationController 也就不是什么难事儿了。

常用方法

AnimationController 常用方法包括:

  • animateBack,用于执行当 AnimationControllervalue 达到指定值时,进行反向操作例如:

    controller.addListener(() {
        if(controller.value > 0.5){
            controller.animateBack(0.1,duration: Duration(seconds: 2));
        }
    });
    

    在上面的代码中,当 AnimationControllervalue 值逐渐递增直到大于 0.5 时,会在两秒内反向逐渐减小,直到 0.1,然后动画停止。

  • animateTo,将 AnimationControllervalue 逐渐过渡到指定值,可以指定过渡时间。

    注意,该方法中的 target 参数,不能大于 AnimationController 的 upperBound。

  • animateWith,根据设定的值模拟仿真动画(我个人觉得这个方法以及其参数就是所谓的“物理动画”)

  • fling,可以根据我们手指滑动(甩出)的速度(velocity)、力量(force)等来模拟一个手指甩出动画,因此它的动画值可以在[0.0,1.0]范围之外,可以实现“物理动画”的效果。

  • dispose(),停止动画,释放动画资源

  • forward,开始动画,其参数是动画起始值

  • repeat,重复动画,其参数中的 minmax 就是重复的区间

  • stop(),停止动画

  • reset,重置动画,将动画值设置为 lowerBound 并停止动画

  • reverse,反向播放动画

  • status,获取动画的当前状态

注意,一定要记得释放动画资源

状态和监听

Flutter 中动画共分为四个状态,由一个枚举类定义:

enum AnimationStatus {
  dismissed,
  forward,
  reverse,
  completed,
}

AnimationController 也提供了一系列方法来监控动画状态:

  • isAnimating,动画是否正在运行
  • isCompleted,动画是否完成
  • isDismissed,动画是否结束

想要获取动画的状态,需要为动画设置监听器:

  • addListener,监听动画的值
  • removeListener,移除动画监听器
  • addStatusListener,监听动画的状态
  • removeStatusListener,移除动画状态监听器

示例

看一个简单的例子:

class AnimationRouteState extends State<AnimationRoute>
    with TickerProviderStateMixin {
  AnimationController animationController;

  @override
  void initState() {
    super.initState();
    // 创建 AnimationController,用于控制动画
    // 必须提供动画时间
    animationController = new AnimationController(
        lowerBound: 100,
        upperBound: 400,
        vsync: this,
        duration: Duration(milliseconds: 1000));
    animationController.addListener(() {
      setState(() {});
      //当动画执行完成时,动画重复(并反向)
      if(animationController.isCompleted){
        animationController.repeat(reverse: true);
      }
    });
    // 开始播放动画
    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Anim Demo 2'),
      ),
      body: Container(
        alignment: Alignment.center,
        child: Container(
          width: animationController.value,
          color: Colors.lightBlue,
          height: animationController.value,
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    // 动画使用完成后必需要销毁
    animationController.dispose();
  }
}

其效果如下:

results matching ""

    No results matching ""