Flutter 动画学习

简介: Flutter 动画学习
概念理解
一个物体的属性包括:大小(Size),透明(Opacity),旋转(Rotation) 滑行(Slide)

动画是驱动器,动画属性,曲线快慢(时间间隔) ,多个动画公用一个驱动器的时候,可以让某一段时间运行某一个动画

驱动器负责心跳

曲线和动画属性共同提供动画当前的属性值

动画本质

1.改变Widget的属性值

2. 估值器 插值器 然后作用到controller上面,controller获取对应的值作用到Widget

3. 范围 快慢 时间 是否重复 获取对应的值来改变Widget

插值器/估值器

为了使得动画呈现出丰富的动画效果,就需要使用非线性动画,插值器与估值器可以解决这个问题。概念如下所示:

  1. 插值器:设置属性值从初始值过渡到结束值的变化规律,如匀速、加速及减速等等。即确定了动画效果变化的模式,如匀速变化、加速变化等等。主要应用于实现非线性运动的动画效果。
  2. 估值器:设置属性值从初始值过渡到结束值的变化具体数值。估值器的作用是协助插值器实现非线性运动的动画效果。插值器决定值的变化规律(匀速、加速),即决定的是变化趋势,而接下来的具体变化数值则交给估值器。如:动画进行了50%(初始值=100,结束值=200 ),那么匀速插值器计算出了当前属性值改变的百分比是50%,那么估值器则负责计算当前属性值 = 100 + (200-100)x50% = 150。插值器其实并不复杂,就是一个数学函数,设置属性值从初始值过渡到结束值的变化规律。每个平台都有自己定义好的一系列插值器,可以供开发者选择使用,也提供自定义的接口,本质上是一个贝塞尔函数。
Flutter中的动画类型

Flutter中动画分为两类,如下所示:

  1. 补间(Tween)动画:定义开始点、结束点、时间和速度等参数,然后由框架自动计算如何从开始点过度达到结束点。
  2. 基于物理的动画:模拟真实世界的行为。例如,当你掷球时,球在何处落地,取决于抛球速度有多快、球有多重、距离地面有多远。
动画 Animation
  1. Tween (start-end)补间对象,用于计算动画使用的数据范围之间的插值。
  2. AnimationStatus()
  3. Listeners和StatusListeners 用于监听动画状态改变
  4. object 属性
  5. AnimationController 控制器
  6. CurvedAnimation 用于定义非线性曲线动画
Tween (估值器 给出范围的值)

开始值和结束值之间的线性插值

如果你想在一个范围内做插值会很有用吗


_animation = _controller.drive(
  Tween<Offset>(
    begin: const Offset(100.0, 50.0),
    end: const Offset(200.0, 300.0),
  ),
);

_animation = Tween<Offset>(
  begin: const Offset(100.0, 50.0),
  end: const Offset(200.0, 300.0),
).animate(_controller);


Tween 子类
子类
ReverseTween 一个[补间],它以相反的方式计算它的[父]
ColorTween 两种颜色之间的插值,使用Color.lerp
SizeTween 两个尺寸之间的插值,使用Size.lerp
RectTween Rect.lerp
IntTween 两个整数之间的补全运算
StepTween 两个整型之间的插值
ConstantTween 具有常数值的补间
CurveTween
AnimatedWidget 当给定的[Listenable]更改值时重新构建的小部件

T lerp(double t) {
  assert(begin != null);
  assert(end != null);
  //返回值 = 开始值 + (结束值 - 开始值) * 传入值
  return begin + (end - begin) * t;}

@overrideT transform(double t) {
  //开始
  if (t == 0.0)
    return begin;
  //结束
  if (t == 1.0)
    return end;
  //中间值  
  return lerp(t);}
  
AnimatedWidget 对于没有附加状态的简单情况,可以考虑使用
class Spinner extends StatefulWidget {
  @override
  _SpinnerState createState() => _SpinnerState();
}

class _SpinnerState extends State<Spinner> with TickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 10),
      vsync: this,
    )..repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    return SpinningContainer(controller: _controller);
  }
}

class SpinningContainer extends AnimatedWidget {
  const SpinningContainer({Key key, AnimationController controller})
      : super(key: key, listenable: controller);

  Animation<double> get _progress => listenable;

  @override
  Widget build(BuildContext context) {
    return Transform.rotate(
      angle: _progress.value * 2.0 * math.pi,
      child: Container(width: 200.0, height: 200.0, color: Colors.green),
    );
  }
}
AnimatedWidget 的子类
子类
RotationTransition 旋转
SlideTransition 动画小部件相对于其正常位置的位置
ScaleTransition 缩放比例
SizeTransition 动画自己的大小和剪辑,并对齐其子女
FadeTransition 透明
RelativeRectTween 两个相对矩形之间的内插 使用RelativeRect.lerp
PositionedTransition 只有当它是[Stack]的子元素时才有效
DecoratedBoxTransition [DecoratedBox]的动画版本,它可以动画化[Decoration]的不同属性
AlignTransition 使其[Align]具有动画效果的[Align]的动画版本。对齐]属性
DefaultTextStyleTransition 画版本的[DefaultTextStyle],它的[TextStyle]的不同属性///动画
AnimatedBuilder 用于构建动画的通用小部件
AnimatedBuilder 对于涉及其他状态的更复杂的情况,请考虑使用
 class Spinner extends StatefulWidget {
   @override
   _SpinnerState createState() => _SpinnerState();
 }

 class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
   AnimationController _controller;

   @override
   void initState() {
     super.initState();
     _controller = AnimationController(
       duration: const Duration(seconds: 10),
       vsync: this,
     )..repeat();
   }

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

   @override
   Widget build(BuildContext context) {
     return AnimatedBuilder(
       animation: _controller,
       child: Container(
         width: 200.0,
         height: 200.0,
         color: Colors.green,
         child: const Center(
           child: Text('Wee'),
         ),
       ),
       builder: (BuildContext context, Widget child) {
         return Transform.rotate(
           angle: _controller.value * 2.0 * math.pi,
           child: child,
         );
       },
     );
   }
 }
AnimationStatus
状态 说明
dismissed 动画一开始就停止了
forward 动画从头到尾都在播放
reverse 动画从结束到开始倒着播放
completed 动画在最后停止
Listenable

void addListener(VoidCallback listener);


void removeListener(VoidCallback listener);


void addStatusListener(AnimationStatusListener listener);


void removeStatusListener(AnimationStatusListener listener);

AnimationController
属性 说明
Duration 这个动画应该持续多长时间
debugLabel 是一个字符串,用于在///调试期间帮助识别此动画(由[toString]使用)
lowerBound 为该动画所能获得的最小值和///该动画被视为被取消的值。它不能是/// null。
upperBound 是该动画可以获得的最大值和///被认为完成该动画的值。它不能是/// null。
TickerProvider Ticker的提供者,Ticker的主要作用是每个动画帧调用一次它的回调,作用就显而易见了,相当于给动画添加了一个动起来的引擎


TickerFuture forward({ double from }) {}

TickerFuture reverse({ double from }) {}


TickerFuture repeat({ double min, double max, Duration period }) {}


TickerFuture fling({ double velocity: 1.0 }) {}


void stop({ bool canceled: true }) {}

void dispose() {}

class Foo extends StatefulWidget {
  Foo({ Key key, this.duration }) : super(key: key);

  final Duration duration;

  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this, // the SingleTickerProviderStateMixin 
      //vsync传入是防止动画离屏之后继续消耗资源
      duration: widget.duration,
    );
  }

  @override
  void didUpdateWidget(Foo oldWidget) {
    super.didUpdateWidget(oldWidget);
    _controller.duration = widget.duration;
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(); 
  }
}



Future<void> fadeOutAndUpdateState() async {
  try {
    await fadeAnimationController.forward().orCancel;
    await sizeAnimationController.forward().orCancel;
    setState(() {
      dismissed = true;
    });
  } on TickerCanceled {
    // the animation got canceled, probably because we were disposed
  }
}

CurvedAnimation(插值器 范围内值的变化快慢)

Curves 一组常见的动画缓动曲线

CurveTween 可以用来将[曲线]应用到[动画]中

 final Animation<double> animation = _controller.drive(
  CurveTween(curve: Curves.ease),
 );
  final Animation<double> animation = CurvedAnimation(
  parent: controller,
  curve: Curves.easeIn,
  reverseCurve: Curves.easeOut,
);
TweenSequence
   final Animation<double> animation = TweenSequence(
     <TweenSequenceItem<double>>[
       TweenSequenceItem<double>(
         tween: Tween<double>(begin: 5.0, end: 10.0)
           .chain(CurveTween(curve: Curves.ease)),
         weight: 40.0,
       ),
       TweenSequenceItem<double>(
         tween: ConstantTween<double>(10.0),
         weight: 20.0,
       ),
       TweenSequenceItem<double>(
         tween: Tween<double>(begin: 10.0, end: 5.0)
           .chain(CurveTween(curve: Curves.ease)),
         weight: 40.0,
       ),
     ],
   ).animate(myAnimationController);

Animatable.animate 和 Animatable.chain

SingleTickerProviderStateMixin

vsync对象会绑定动画的定时器到一个可视的Widget,所以当Widget不显示时,动画定时器将会暂停,当Widget再次显示时,动画定时

器重新恢复执行,这样就可以避免动画相关UI不在当前屏幕时消耗资源。如果要使用自定义的State对象作为vsync时,请包含

TickerProviderStateMixin

动画流程


其他

github

参考文章
  1. Flutter动画详解
  2. flutter源码
相关文章
|
3天前
|
设计模式 移动开发 开发框架
如何学习 Flutter 框架?
学习 Flutter 需要耐心和持续的努力,通过系统的学习、实践、交流和不断跟进最新技术,你将逐渐掌握 Flutter 框架,并能够开发出高质量的移动应用。
|
13天前
|
开发工具 UED 容器
Flutter&鸿蒙next 实现长按录音按钮及动画特效
本文介绍了如何在 Flutter 中实现一个带有动画效果的长按录音按钮。通过使用 `GestureDetector` 监听长按手势,结合 `AnimatedContainer` 和 `AnimationController` 实现按钮的动画效果,以及 `flutter_sound` 插件完成录音功能。文章详细讲解了功能需求、实现思路和代码实现,帮助读者逐步掌握这一实用功能的开发方法。
90 5
|
15天前
|
前端开发 开发者
深入探索 Flutter 鸿蒙版的画笔使用与高级自定义动画
本文深入探讨了 Flutter 中的绘图功能,重点介绍了 CustomPainter 和 Canvas 的使用方法。通过示例代码,详细讲解了如何绘制自定义图形、设置 Paint 对象的属性以及实现高级自定义动画。内容涵盖基本绘图、动画基础、渐变动画和路径动画,帮助读者掌握 Flutter 绘图与动画的核心技巧。
64 1
|
16天前
|
存储 缓存 JavaScript
Flutter 学习之封装 WebView
【10月更文挑战第24天】通过以上的探讨,我们可以看出,在 Flutter 中封装 WebView 是非常有必要的,它可以提高代码的复用性、增强可维护性、提供统一接口。在实际应用中,我们需要根据具体的需求和场景,选择合适的封装方法和技术,以实现更好的效果。
|
21天前
动画控制器在 Flutter 中的工作原理
【10月更文挑战第18天】总的来说,动画控制器 `AnimationController` 在 Flutter 中起着关键的作用,它通过控制动画的数值、速度、节奏和状态,实现了丰富多彩的动画效果。理解它的工作原理对于我们在 Flutter 中创建各种精彩的动画是非常重要的。
|
1月前
|
Dart 开发者 Windows
flutter:dart的学习
本文介绍了Dart语言的下载方法及基本使用,包括在Windows系统上和VSCode中的安装步骤,并展示了如何运行Dart代码。此外,还详细说明了Dart的基础语法、构造函数、泛型以及库的使用方法。文中通过示例代码解释了闭包、运算符等概念,并介绍了Dart的新特性如非空断言操作符和延迟初始化变量。最后,提供了添加第三方库依赖的方法。
28 12
|
1月前
|
UED
flutter:动画&状态管理 (十三)
本文档介绍了Flutter中`animatedList`的使用方法和状态管理的示例。`animatedList`用于创建带有动画效果的列表,示例代码展示了如何添加、删除列表项,并执行相应的动画效果。状态管理部分通过一个简单的点击切换颜色的示例,演示了如何在Flutter中管理组件的状态。
|
3月前
|
前端开发
Flutter快速实现自定义折线图,支持数据改变过渡动画
Flutter快速实现自定义折线图,支持数据改变过渡动画
91 4
Flutter快速实现自定义折线图,支持数据改变过渡动画
|
3月前
|
Dart 开发工具 Android开发
Flutter学习:从搭建环境到运行
Flutter学习:从搭建环境到运行
45 0
|
4月前
|
索引
flutter-其他学习
flutter-其他学习