Flutter学习总结(二十、Flutter的动画)

Flutter的动画

一起从0开始学习Flutter!

为了让我们的场景切换更加流畅和一些元素更能抓住用户的眼球,我们在APP中都会添加多种动画来装扮我们的APP,在以往的开发中对于普通的旋转位移,缩放动画我们都有一些简单的处理方式,但是面对复杂的动画我们都会耗费我们大量的时间来进行计算,我们一起来针对Flutter中的动画进行学习,看下在Flutter中我们如何处理我们日常使用的动画。
在Flutter中也为我们提供了多种动画示例,我们稍后看下,我们先看下如何不使用这些动画示例来创建一个我们想要的动画。
我们首先需要一个动画的控制单元,在Flutter中AnimationController来充当这个角色,我们先认识一下AnimationController:

AnimationController

AnimationController({
    double value, //给定动画的初始状态
    this.duration,//动画执行的时间间隔,如果没有设置reverseDuration则返回时的持续时间也是duration指定的时间
    this.reverseDuration,//返回原来状态的动画运行时间
    this.debugLabel,//调试的标签
    this.lowerBound = 0.0,//动画消失时的值
    this.upperBound = 1.0,//动画完成时的值
    this.animationBehavior = AnimationBehavior.normal,//如果设置为Normal如果设置的disableAnimations为True则不会浪费时间,如果设置为 AnimationBehavior.preserve则会消耗同样的时间
    @required TickerProvider vsync,//防止屏幕外动画,消耗不必要的资源
  })

范围控制我们看到在AnimationController为我们提供了0-1的控制,但是在实际使用中很多情况是无法满足我们需求的,我们这时候需要Tween来帮助我们做一个范围的设定,可以设定动画变化的范围。Tween提供了多种样式的变化,如:IntTween,ColorTween,RectTween等变化的范围设定。我们简单来了解下他们,然后可以根据需要在使用的时候进行选择。

IntTween({ int begin, int end }) : super(begin: begin, end: end);//开始的数值,和结束的数值,都是提供的整数
ColorTween({ Color begin, Color end }) : super(begin: begin, end: end);//开始的颜色,和结束的颜色,提供的是颜色值

我们把他们结合起来看可以做些什么:

	controller = AnimationController(
        duration: Duration(milliseconds: 1000), vsync: this);//创建一个动画的控制器
    Tween tween = Tween<double>(begin: 100.0, end: 400.0);//创建一个动画调整大小的限定器
    animation = tween.animate(controller);//将限定器与控制器进行绑定,就可以得到一个Animation对象
    animation.addListener(() {//当屏幕上每一帧变化的时候都会在这里进行刷新通知,每次刷新都调用我们build方法重绘当前控制的元素
      setState(() {});
    });
    controller.forward();//开始执行动画

如果我们想要监听动画的开始和结束需要给animation添加状态监听:

	animation.addStatusListener((status) {
      if(status == AnimationStatus.completed){//如果当前状态是已经完成了动画则往下执行
        controller.reverse(from:1.0);//将动画反向执行一遍
      }
    });

有了动画的控制我们只需要根据返回的状态值,控制build里面的元素显示就可以了,比如我们控制Flutter图标的一个放大动画:

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10.0),
        height: animation.value,//这里根据返回的限定值进行刷新,将logo显示为指定的大小
        width: animation.value,//这里根据返回的限定值进行刷新,将logo显示为指定的大小
        child: FlutterLogo(),显示的Flutter图标的组件
      ),
    );
  }

其他的动画比如位移和旋转我们可以控制margin和transform的设置,具体的属性设置可以参照之前我们介绍容器时的参数说明。
这样虽然能帮助我们实现动画,如果我们需要重复利用这个动画则需要实现多处,我们这时候可以使用AnimatedWidget来帮助我们做一些简化,Flutter为我们提供了一些AnimatedWidget的示例,比如FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition。这些是已经帮我们做好的了动画模式。我们帮上面的例子通过AnimatedWidget来改造一下。

class ImageAnimationWidget extends AnimatedWidget {//创建一个ImageAnimationWidget继承自AnimatedWidget来实现动画

  ImageAnimationWidget({Key key, Animation<double> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10.0),
        height: animation.value,
        width: animation.value,
        child: FlutterLogo(),
      ),
    );
  }
}

这块的代码就是我们刚刚State里的build代码,我们把动画部分提取了出来,这样我们在以后需要多个该动画时直接引用即可,原来的build代码,现在已经被替换为了:

@override
  Widget build(BuildContext context) {
    return ImageAnimationWidget(animation: animation,);
  }

还是上面的例子,如果我们想要使用Flutter为我们提供的示例来实现怎么做呢:

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(scale: animation,child: FlutterLogo(),);
  }

就是把State里的build方法替换为了ScaleTransition,然后我们需要修改animation中的Tween的开始结束大小,方便了很多,其他的动画我们可以自己进行实验一下。

通过本篇我们学习了一些简单的动画,Flutter的基础学习也告一段落,接下来需要开一个新的专题,一起学习一个项目的0开始。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章