flutter3.0学习笔记

CurvedAnimation

Preview

CurvedAnimation也是Animation的实现,只不过它可以根据Curve曲线来生成非线性的区间值。CurvedAnimation并不能驱动动画,它只是一个数值的转换器。我们可以通过CurvedAnimation来指定动画的曲线。

CurvedAnimation类接受三个参数:

  • parent:参数传入一个Animation对象,比如AnimationController
  • curve:控制动画变化的速率
  • reverse:反转曲线的方向
CurvedAnimation({
    required this.parent,
    required this.curve,
    this.reverseCurve,
  })

用法:

//通过CurvedAnimation来指定动画的曲线
final _curvedAnimation = CurvedAnimation(
    parent: _controller,
    curve: Curves.bounceOut
);
  • 例子1:

结合上一章Animation里的例子中并没有指定Curve,所以放大的过程是线性的(匀速),下面我们指定一个Curve,来实现一个类似于弹簧效果的动画过程。我们只需要将initState中的代码改为下面这样即可:

void initState() {
    // TODO: implement initState
    super.initState();
    //创建动画控制器
    _controller = AnimationController(
        duration: const Duration(seconds: 2),
        vsync: this
    );
    //指定一个Curve
    _animation = CurvedAnimation(parent: _controller, curve: Curves.bounceInOut);
    //使用Tween图片宽高从0变到300
    //_animation = Tween(begin: 0.0,end: 300.0).animate(_controller);
    _animation = Tween(begin: 0.0,end: 300.0).animate(_animation);
    //监听动画,并且更新ui
    _controller.addListener(() {
      setState(() {
       //监听插值变化
       print(_animation.value);
      });
    });
    _controller.addStatusListener((status) {
      print(status);
      //AnimationStatus.forward(动画正在正向执行)
      //AnimationStatus.completed( 动画在终点停止)
      //AnimationStatus.dismissed(动画在起始点停止)
      //AnimationStatus.reverse(动画正在反向执行)

    });
    //启动动画正向执行
    _controller.forward();
  }
  • 例子2:

结合上章AnimationController的篮球弹跳例子,我们给弹跳动画加上curve。那么球弹跳的动作就比较流畅

import 'package:flutter/material.dart';

class CurvedAnimationPage extends StatefulWidget {
  const CurvedAnimationPage({Key? key}) : super(key: key);

  @override
  State<CurvedAnimationPage> createState() => _CurvedAnimationPageState();
}

class _CurvedAnimationPageState extends State<CurvedAnimationPage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: this
    );
    final curvedAnimation = CurvedAnimation(
      parent: _controller,
      curve: Curves.fastOutSlowIn
    );
    //通过Tween来生成不同的区间范围值,Tween不保存任何状态,它只是起始值的变换函数。
    _animation = Tween<double>(begin:600 ,end: 400).animate(curvedAnimation);
    _controller.addListener(() {
      //监听插值变化
      setState(() {
        //print(_animation.value);
      });
    });
   _controller.repeat(reverse: true);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('CurvedAnimation'),),
      body: Stack(
        children: [
          Image.asset(
            'images/qiuc.jpeg',
            fit: BoxFit.cover,
            height: double.infinity,
            width: double.infinity,
          ),
          Transform.translate(
            offset:  Offset(250,_animation.value),//改变y的偏移量
            child: Image.asset(
              'images/qiu.png',
              fit: BoxFit.contain,
              height: 70,
              width: 70,
            ),
          )
        ],
      ),
    );
  }
}

效果: curve.gif