Flutter 动画入门

简介

  • Flutter动画核心类:Animation类,它可以判断当前动画的状态(开始,停止,移动,前进,反向),它是由AnimationController管理的,并通过Listeners和StatusListeners管理动画状态的所发生的变化,我们先对动画有了大体的了解,下面我们对其中提到的类进行逐一学习
  • 这次主要学习flutter动画中的 平移,缩放,旋转,透明度,插值器,是为之后的自定义动画做准备嗷!

Animation

  • Animation对象本身随手记屏幕是无感知的,,它仅仅直到当前动画的插值和状态,,Animation对象是一个在一段时间内,一次生成一个区间值的类,其输出值可以是线性的、非线性的,控制器可以控制Animation的动画方式:正向、反向、中间进行切换。

Animatable

  • Animatable是控制动画类型的类,比如我们需要控制动画过程中颜色值的变化,那么Animatable就用来控制色值的变化

AnimationController

  • 上面提到的动画控制器即AnimationController,它负责在给定的时间段内,以线性的方式生成默认区间为(0.0, 1.0)的数字,我们可以通过AnimationController来创建Animation对象
// vsync: 该参数接受的是TickerProvidr(宿主)类型的对象,作用是阻止在屏幕锁屏时执行动画以避免不必要的资源浪费
AnimationController _controller = AnimationController(vsync: this, duration: duration)
AnimationController 的常用操作说明
属性说明
controller.forward()正向开始执行动画
controller.reverse()反向开始执行动画
controller.reset()重置动画到初始状态
controller.dispose()取消/停止动画
AnimationStatus 动画状态说明
属性说明
AnimationStatus.forward执行controller.forward() 会回调此状态
AnimationStatus.reverse执行controller.reverse() 会回调此状态
AnimationStatus.dismissed动画从controller.reverse() 反向执行 结束时会回调此方法
AnimationStatus.completed动画从controller.forward() 正向执行 结束时会回调此方法

Tween补间动画

  • 通常AnimationController的取值范围是(0.0,1.0), 但是有些时候我们呢可能会需要不同范围或者类型的值,就需要使用Tween来定义并生成相应的值,例如:
// 缩放取值变化范围(1.0, 0.8)
Animation<double> _scaleAnimation = _scaleAnimation = Tween<double>(begin: 1, end: 0.8).animate(_controller);
  • 释义:
    • Tween作用:定义从输入范围(左区间)到输出范围(右区间)的映射
    • Tween继承自Animatable,例如上面的例子随着动画改变色值:
final Tween _colorTween = ColorTween(begin : Colors.transparent, end:Colors.black54);
示例实现平移补间动画

import 'package:flutter/material.dart';


class SlideTransitionAnimationWidget extends StatefulWidget {
  @override
  SlideTransitionAnimationWidgetState createState() => new SlideTransitionAnimationWidgetState();
}


class SlideTransitionAnimationWidgetState extends State<SlideTransitionAnimationWidget>
    with SingleTickerProviderStateMixin {
  final Duration _duration = const Duration(milliseconds: 300);
  AnimationController _controller;
  Animation<Offset> _animation;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SlideTransition'),
      ),
      body: Center(
        child: SlideTransition(
          position: _animation,
          child: Container(
            height: 100,
            width: 100,
            color: Colors.black,
          ),
        ),
      ),
    );
  }


  @override
  void initState() {
    _controller = AnimationController(vsync: this, duration: _duration);
    _animation = Tween<Offset>(begin: Offset(-1, 0), end: Offset(0, 0))
        .animate(_controller)
          ..addListener(() {
            // AnimationController产生的数值取决于屏幕刷新情况,一秒60帧
            // 数值生成之后,每个Animation对象都会通过Listener进行回调,下面实现动画监听
            setState(() {
              print(_animation.value);
            });
          })
          ..addStatusListener((status) {
            // 实现动画循环
            if (status == AnimationStatus.completed) {
              // 正向结束时回调
              _controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              // 反向执行 结束时会回调此方法
              _controller.forward();
            }
          });
    _controller.forward();
  }


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

在这里插入图片描述

示例实现缩放动画
添加
// 声明处:
Animation<double> _scaleAnimation;
// initState中
_scaleAnimation = Tween<double>(begin: 1.0, end: 
0.5).animate(_controller);

// build中修改
body: Center(
  child: ScaleTransition(
    scale: _scaleAnimation,
    child: Container(
      height: 100,
      width: 100,
      color: Colors.black,
    ),
  ),
),

在这里插入图片描述

  • 实现方式都是相同的,大家可以再尝试旋转以及透明效果
    在这里插入图片描述

Curve

  • Curve类似于Android中的插值器,插值器如果不了解可以看一下这篇文章
  • 通过Curve,可以将动画过程设置为线性或者非线性,初始化如下:
final Curanimation curve = CurveAnimation(parent:controller, curve:Curves/easeIn);
示例将弹跳的插值器和透明度结合

import 'package:flutter/material.dart';


class SlideTransitionAnimationWidget extends StatefulWidget {
  @override
  SlideTransitionAnimationWidgetState createState() => new SlideTransitionAnimationWidgetState();
}


class SlideTransitionAnimationWidgetState extends State<SlideTransitionAnimationWidget>
    with SingleTickerProviderStateMixin {
  final Duration _duration = const Duration(milliseconds: 3000);
  AnimationController _controller;
  Animation<Offset> _slideAnimation;
  Animation<double> _scaleAnimation;
  Animation<double> _fadeAnimation;
  Animation<double> _rotationAnimation;
  Animation<double> _curveAnimation;
  final _opacityTween = Tween<double>(begin: 0.1 ,end: 1.0);


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SlideTransition'),
      ),
      body: Center(
        // 做相应动画可以直接修改此处,看下源码动画的参数是什么即可
        child: Opacity(
          // 计算差值,就相当于在自定义的插值器前面设置一个数值转换器
          // 将透明度的设置和弹跳的插值器结合,evaluate作用是使得弹跳的进度即为透明度设置的进度
          opacity : _opacityTween.evaluate(_curveAnimation),
          child: Container(
            height: 100,
            width: 100,
            color: Colors.black,
          ),
        ),
      ),
    );
  }


  @override
  void initState() {
    _controller = AnimationController(vsync: this, duration: _duration);
    _scaleAnimation = Tween<double>(begin: 1.0, end: 0.5).animate(_controller);
    _fadeAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(_controller);
    _rotationAnimation = Tween<double>(begin: 0.0, end: 60.0).animate(_controller);
    _curveAnimation = CurvedAnimation(parent: _controller, curve: Curves.bounceIn);
    _slideAnimation = Tween<Offset>(begin: Offset(-1, 0), end: Offset(0, 0))
        .animate(_controller)
          ..addListener(() {
            // AnimationController产生的数值取决于屏幕刷新情况,一秒60帧
            // 数值生成之后,每个Animation对象都会通过Listener进行回调,下面实现动画监听
            setState(() {
              print(_slideAnimation.value);
            });
          })
          ..addStatusListener((status) {
            // 实现动画循环
            if (status == AnimationStatus.completed) {
              // 正向结束时回调
              _controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              // 反向执行 结束时会回调此方法
              _controller.forward();
            }
          });
    _controller.forward();
  }


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

在这里插入图片描述

Demo地址

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页