美文网首页FlutterFlutter记录自学flutter点点滴滴
Flutter 学习之旅(三十四) Flutter 动画(一)

Flutter 学习之旅(三十四) Flutter 动画(一)

作者: Tsm_2020 | 来源:发表于2020-09-14 16:10 被阅读0次

    Flutter 中的动画由 Animation、Curve、Controller、Tween共同组成,每一个组件都有他们特定的职责,
    下面我们一个一个介绍

    AnimationController

      AnimationController({
        double value,
        ///动画过渡时间
        this.duration,
        this.reverseDuration,
        this.debugLabel,
        ///动画开始的值
        this.lowerBound = 0.0,
        ///动画结束的值
        this.upperBound = 1.0,
        this.animationBehavior = AnimationBehavior.normal,
        ///用来改变过程中的value的
        @required TickerProvider vsync,
      })
    

    AnimationController用于控制动画,它包含动画的正向执行forward()、停止stop() 、反向播放 reverse()等方法。他的区间是(0~1) 不可以超过这个区间 ,并在预定时间内将这个数据不断的由一端过度到另一端,每一帧都会生成一个新的值,这个过度的速度是由Curve 来控制的, 屏幕每一次刷新都是一帧,每一帧都会调用 TickerProvider来刷新当前的动画的过渡值,并利用这个过渡值来构建当前的动画状态
    AnimationController 可以使用addListener 可以获取动画过渡的值,addStatusListener 可以监听状态发生改变,
    如果想要重复执行一个正向动画 forward(),

      _controller
            ..value=0
            ..forward();
    

    注意这里如果想要每次都执行这个动画,必须重置这个value,这个问题困扰了我很久,
    并且在widget 的dispose 的方法内取消注册

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

    TickerProvider 用来改变过程中的value的,使用的方法是 混入到需要的widget 中,通常为 SingleTickerProviderStateMixin,具体的作用原理还不是很理解,这里只能后来再完善了

    Animation

    Animation 是一个抽象类,他保存了动画的插值和状态,他在一定时间内依次生成Tween之间的值,获取的这个值可以是均匀的,也可是先快后慢等 ,这是由Curve决定的 ;动画不仅正向运行,也可以反向运行,一些比较常用的Animation 类比如Animation <double> ,Animation <Size>,Animation <Color>,Animation <Offset>等,这里我们需要记住一个比较重要的知识点,那就是Animation 存了动画的插值和状态,我们可以按照动画正向即从0~1开始执行,如果我们想要获取 0.5的时候的值,则使用Tween.transform 则可以获得,这是一个非常重要的点.

    Curve

    Curve是用来控制动画执行的速度的,flutter 中就是利用Curve来控制这个速度,并把匀速的线性动画称为
    Curves.linear ,将AnimationController利用CurvedAnimation 进行包装,
    例子

        animatedContainer = AnimationController(
            duration: Duration(seconds: 2),
            lowerBound: 0,
            upperBound: 1,
            vsync: this);
    
        ///改变起始值
        Animation curve =
            CurvedAnimation(parent: animatedContainer, curve: Curves.easeIn,);
    

    Tween

    默认情况下AnimationController的数据是否0-1执行的,但是我们需要将它放大到0-100怎么执行呢,这里使用
    Tween 改变起始值就可以了,并使用tween.animate()来获取动画对象
    例子

    _tween=IntTween(begin: 0, end: 255)
    anim=_tween.animate(_tween);
    

    同样可以封装ColorTween

        tween=ColorTween(begin: widget.begin,end: widget.end) ;
        anim=tween.animate(CurvedAnimation(parent: _controller,curve: Curves.easeOut));
    

    下面写一个简单的例子
    这个例子是控制文本的颜色Color.fromARGB(animation.value, 1, 1, 1),只需要从0-255 之间就可以了
    然后先正向执行,再反向执行无限重复这个动画,

    class _TsmAnimationState extends State<TsmAnimationPage>
        with SingleTickerProviderStateMixin {
      Animation<int> animation;
      AnimationController animatedContainer;
    
      @override
      void initState() {
        animatedContainer = AnimationController(
            duration: Duration(seconds: 2),
            lowerBound: 0,
            upperBound: 1,
            vsync: this);
    
        ///添加变速模型
        Animation curve =
            CurvedAnimation(parent: animatedContainer, curve: Curves.easeIn,);
    
         ///改变起始值
        animation = IntTween(begin: 0, end: 255).animate(curve);
    
    
       
        animatedContainer.addListener(() {
          setState(() {
            printString("value:${animation.value}");
          });
        });
        animatedContainer.addStatusListener((status) {
          if(status==AnimationStatus.completed){
            animatedContainer.reverse();
          }else if(status==AnimationStatus.dismissed){
            animatedContainer.forward();
          }
        });
        animatedContainer.forward();
        super.initState();
      }
    
      @override
      void dispose() {
        animatedContainer.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Animation 学习"),
            centerTitle: true,
          ),
          body: Container(
            child: Center(
              child: Text(
                "重复渐隐动画",
                style: TextStyle(
                  color: Color.fromARGB(animation.value, 1, 1, 1),
                ),
              ),
            ),
          ),
        );
      }
    }
    

    效果图


    GIF 2020-9-15 9-33-51.gif

    我学习flutter的整个过程都记录在里面了
    https://www.jianshu.com/c/36554cb4c804

    最后附上demo 地址

    https://github.com/tsm19911014/tsm_flutter

    相关文章

      网友评论

        本文标题:Flutter 学习之旅(三十四) Flutter 动画(一)

        本文链接:https://www.haomeiwen.com/subject/hklzektx.html