Flutter常用动画

2020-12-24  本文已影响0人  刘铁崧

Animation类——抽象类
包含:
监听动画值的改变
监听动画状态的改变
value(获取当前值)
status(获取当前状态)

开发中我们通常使用子类AnimationController(继承自Animation)
-flutter中渲染时必须收到一个同步信号vsync,GPU才会进行下一步渲染
-使用AnimationController时要传入一个vsync,需要将当前widget传入,但是要混入SingleTickerProviderStateMixin类
(vsync的作用:程序退出后台后控制动画的绘制)
-forward(向前执行动画)
-reverse(动画反转)

CurvedAnimation类(设置动画执行的速率)(速度曲线)
官方文档:https://api.flutter.dev/flutter/animation/Curves-class.html

Tween类(设置动画执行的value范围)
begin(开始值)
end(结束值)

简单实用 —— 实现放大缩小动画(心跳效果)

效果:

流程:
初始化函数中穿件动画
设置动画效果CurvedAnimation
设置动画执行value(不设置默认为0.0 - 1.0范围)
addListener监听动画值的改变,并刷新(影响性能)
addStatusListener监听动画状态的改变(处理不同状态下的事件)
UI渲染中如果想用到动画设置的value,可以通过Animation对象下的value获取(_animation.value)
dispose析构函数中销毁动画控制器

class _TestNavigatorState extends State<TestNavigator> with SingleTickerProviderStateMixin{
  AnimationController _animationController;
  Animation _animation;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // 创建动画
    _animationController = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this
    );
    // 设置Curve
    _animation = CurvedAnimation(parent: _animationController, curve: Curves.easeInOut);
    // 设置Tween
    _animation = Tween(begin: 50.0,end: 100.0).animate(_animation);

    // 监听动画值的改变
    _animationController.addListener(() {
      setState(() {

      });
    });
    // 监听动画状态的改变
    _animationController.addStatusListener((status) {
      if(status == AnimationStatus.completed){// 动画执行完成
        // 反转动画
        _animationController.reverse();
      }
      else if(status == AnimationStatus.dismissed){// 动画状态恢复到初始状态
        _animationController.forward();
      }
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("动画"),
      ),
      body: Center(
          child:Column(
            children: [
              Icon(Icons.favorite,color: Colors.red,size: _animation.value),
              FloatingActionButton(
                child: Icon(Icons.play_arrow),
                onPressed: (){
                  if (_animationController.isAnimating){// 动画正在执行
                    _animationController.stop();
                  }
                  else{// 动画执行结束
                    if (_animationController.status == AnimationStatus.forward){
                      // 动画正向执行
                      _animationController.forward();
                    }
                    else if (_animationController.status == AnimationStatus.reverse){
                      // 动画反转执行
                      _animationController.reverse();
                    }
                    else{
                      _animationController.forward();
                    }
                  }

                  // _animationController.isAnimating ? _animationController.stop() : _animationController.forward();
                },
              )
            ],
          )
      ),
    );
  }
}
  @override
  void dispose() {
    _animationController.dispose();
    // TODO: implement dispose
    super.dispose();
  }

高性能动画优化方案

1. 使用AnimationWidget避免频繁build整个widget

缺点:每次都要创建一个类,并且如果有子类依然会重复build

class HeartAnimation extends AnimatedWidget {
  HeartAnimation(Animation animation):super(listenable:animation);
  @override
  Widget build(BuildContext context) {
    Animation animation = listenable;
    return Icon(Icons.favorite,color: Colors.red,size: animation.value);
  }
}

外部调用时直接使用HeartAnimation()并传入animation

 body: Center(
          child:Column(
            children: [
              HeartAnimation(_animation),
              FloatingActionButton(
                child: Icon(Icons.play_arrow),
                onPressed: (){}
            }
      ),

2.使用AnimatedBuilder(最高效便捷)

AnimatedBuilder(
                animation: _animationController,
                builder: (context,child){
                  return Icon(Icons.favorite,color: Colors.red,size: _animation.value);
                },
),
上一篇 下一篇

猜你喜欢

热点阅读