flutter (笔记) 动画学习

简洁概括:flutter 程序中包含两种动画 代码动画,绘图动画

代码动画是以小部件为中心,它们倾向于增强特定现有小部件的外观或过渡,而不是单独充当独立的小部件。

绘图的动画 是从无到有画出来的。它们通常是独立,如游戏角色,或者涉及纯粹用代码表达具有挑战性的转换。

而我们平常用的动画都是代码动画, 绘制动画更加复杂。

Flutter 代码的动画有两种风格 隐式动画和显式动画

隐式动画依赖于简单地为一些小部件属性设置一个新值,Flutter 负责将其从当前值设置为新值。这些小部件易于使用且功能强大(比如位置的改变、大小的改变等)一般内置都以Animated开头

显式动画需要一个 AnimationController。它们被称为“显式”,因为它们仅在明确要求时才开始制作动画。你可以使用显式动画来做所有你能用隐式动画做的事情,必须手动管理 AnimationController 的生命周期,因为它不是一个小部件,这意味着将它放在一个有状态的小部件中。一般内置都以Transition结尾

所以实现动画的时候要根据自己的需求去决定选择什么动画。

1 我的动画是否会永远重复?我所说的“永远”是指它在某个屏幕上,或者只要某个条件为真,例如音乐播放。

2 动画中的值是否不连续。

3 多个小部件是否以协调的方式一起制作动画 

只要满足一个就选择显示动画

官方动画说明地址  Introduction to animations | Flutter

动画的效果实际看到的是快速连续显示的许多静止图像。这就是电影的运作方式。单独的图片在电影中被称为帧——因为数字屏幕的工作方式类似——它们在这里也被称为帧。电影通常每秒显示 24 帧。现代数字设备每秒显示 60 到 120 帧。

现在再来回顾代码。

实现动画一般都要实现一个方法

实现这个方法的目的是控制器需要

class   ......    with SingleTickerProviderStateMixin{

同时要创建一个控制器

late final AnimationController _controller = AnimationController(
  duration: const Duration(milliseconds: 150),

//需要一个TickerProvider对象
  vsync: this,
);

...省略

}

看下SingleTickerProviderStateMixin 里面有什么

可以看到实现的必须是state 子类 类型必须是StatefulWidget子类

@optionalTypeArgs
mixin SingleTickerProviderStateMixin<T extends StatefulWidget> on State<T> implements TickerProvider {
  Ticker? _ticker;
 //创建一个_ticker
  @override
  Ticker createTicker(TickerCallback onTick) {
        ...省略
         _ticker = Ticker(onTick, debugLabel: kDebugMode ? 'created by         ${describeIdentity(this)}' : null);
        _updateTickerModeNotifier();
        _updateTicker(); // Sets _ticker.mute correctly.
        return _ticker!;
  }

  @override
  void activate() {
    ...省略
  }

  void _updateTicker() {
    ...省略
  }

  void _updateTickerModeNotifier() {
  ...省略
  }
...省略

}

看看 Ticker

描述 每个动画帧调用一次它的回调。 

这里可以明白 动画的每一帧都调用了他的回调

Ticker(this._onTick, { this.debugLabel }) {
  assert(() {
    _debugCreationStack = StackTrace.current;
    return true;
  }());
}

比如

var ticker = Ticker((elapsed) => print('hello'));
ticker.start();

每一帧都会打印, 如果不ticker.dispose()。他会一只运行下去

而 SingleTickerProviderStateMixin   就是为了解决管理的麻烦   Ticker就不用在我们自己管理

同时也可以让flutter框架获取当前sate更多的信息

如果不实SingleTickerProviderStateMixin 现那你AnimationController 要自己去实现一个管理

再来看AnimationController

AnimationController({

//动画的值
  double? value,
//动画持续时间
  this.duration,
//反转时间
  this.reverseDuration,
//调试时候打印自己的标签
  this.debugLabel,
//动画起始值 也可以自定义比如 100
  this.lowerBound = 0.0,
//动画结束值 也可以自定义比如 1000
  this.upperBound = 1.0,
//动画模式
  this.animationBehavior = AnimationBehavior.normal,
  required TickerProvider vsync,
}) : ...省略
     _direction = _AnimationDirection.forward {
//当前state 创建一个对象
  _ticker = vsync.createTicker(_tick);
  _internalSetValue(value ?? lowerBound);
}

官方事例

class _MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin<MyWidget> {
  AnimationController _controller;  int i = 0;  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this, 
      duration: const Duration(seconds: 1),
    );
    _controller.addListener(_update);
    _controller.forward();
  }  void _update() {
    setState(() {
      i = (_controller.value * 299792458).round();
    });
  }  @override
  Widget build(BuildContext context) {
    return Text('$i m/s');
  }
}

这就是一个简单的动画,

隐式动画 内置的Animated开头

解隐动画就是没有控制器,而且不能重复

如 //主要更改自身的属性值的时候setstate 会触发动画
AnimatedContainer({
...省略
//执行曲线
  Curve curve = Curves.linear,
//持续时间
  required Duration duration,
//完成回调
  VoidCallback? onEnd,
}) 

显式动画 内置以Transition 结尾

比如    小部件随意拖动 放开后自动靠边 

Stack(
  children: [
    //内置的动画
    PositionedTransition(
     //Tween 补间,表示一个区间值
      rect: RelativeRectTween(
        //初始位置
        begin: const RelativeRect.fromLTRB(x, y,.,.),
        //结束位置
        end: const RelativeRect.fromLTRB(endX,endY,.,.),
      ).animate(
        CurvedAnimation(
          parent: _controller,
          curve: Curves.elasticOut,
        ),
      ),
      child: null,
    ),
  ],
);
//拖动的时候不断更新动画,让他满足自己动画的标准
onPanUpdate: (details) {
  setState(() {
    x += details.delta.dx;
    y += details.delta.dy;
    endX = 0; \\或者靠右坐标
    endY=y;
  });
},
//拖动结束后开始动画
onPanEnd: (details) {
    _controller.forward();
},

所以上述效果主要就是不断的刷新。动画的初始位置(这里的初始位置就是ui上显示的位置)和动画的结束位置(就是靠边的最终位置)

附上拖动效果的源码 https://pub.dev/packages/gx_floating_widget

 

               

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值