flutter 动画展开菜单_Flutter 强大的动画功能,从理论到实践教程,让你轻松get所有技能包...

99c098ed0e050377ecb5c24779f44c06.png
本文作者:Didier Boelens
原文链接:www.didierboelens.com/2018/06/ani…
翻译: hcc

Flutter中的动画功能强大且易于使用。接下来通过一个具体的实例,您将学到关于 Flutter 动画的一切。

第一次看文章的朋友可以关注我的专栏,每日分享发布Flutter进阶学习技术干货!
Flutter跨平台开发终极之选​zhuanlan.zhihu.com
b2165ddde09823d0c81d51c4e64acef7.png

难度:中级

今天,我们无法想象移动应用程序里面没有任何动画,当您从一页跳转到另一页时,或者点击一个按钮(如 InkWell)... 都会有一个动画。动画无处不在。

Flutter 使动画非常易于实现。

简而言之,这篇文章就是讨论这个话题的,尽管之前只有专家才能谈论,为了让这篇文章显得更有吸引力,我将挑战一下,仿照 Vitaly Rubtsov 在 Dribble 上传的一个 "Guillotine Menu (斩头菜单)"的一个动画效果,用 Flutter 一步步的实现这个效果。

b210e83567082687871b2acb40bc233a.png

本文的第一部分将介绍一下主要的理论知识和概念,第二部分将要实现上面的那个动画效果。

动画中的三大核心

为了能够实现动画效果,必须提供下面的三个元素:

  • Ticker
  • Animation
  • AnimationController

下面对这几个元素进行一下简单的介绍,更详细的在后面说明。

Ticker

简单来说,Ticker 这个类会在常规的一个时间区间里(大约每秒 60 次),发送一个信号,把这想象成你得手表,每秒都会滴答滴答的转。

当 Ticker 启动之后,自从第一个 tick 到来开始,每个到的 tick 都会回调 Ticker 的 callback 方法。

重要提示
尽管所有的 ticker 可能是在不同的时间里启动的,但是它们总是以同步的方式执行,这对于一些同步动画是很有用的。

Animation

Animation 其实没有什么特别的,只不过是一个可以随着动画的生命周期改变的一个值(有特定的类型),值随着动画时间的变化而变化的方式可以是线性的(例如1、2、3、4、5...),也可以更为复杂(参考后面的“Curves 曲线”)。

AnimationController

AnimationController 是一个可以控制一个或多个动画(开始,结束,重复)的控制器。换句话说,它让上面说的 Animation 值在一个指定的时间内,根据一个速度从一个最小值变化到最大。

AnimationController 类介绍

此类可控制动画。为了更加精确,我宁愿说“ 控制一个场景”,因为稍后我们将看到,几个不同的动画可以由同一个控制器来控制……

因此,使用这个AnimationController类,我们可以:

  • 开始一个子动画,正向或者反向播放
  • 停止一个子动画
  • 为子动画设置一个具体的值
  • 定义动画值的边界

以下伪代码可以展示这个类里面的不同的初始化参数

AnimationController controller = new AnimationController(
    value:      // the current value of the animation, usually 0.0 (= default)
    lowerBound: // the lowest value of the animation, usually 0.0 (= default)
    upperBound: // the highest value of the animation, usually 1.0 (= default)
    duration:   // the total duration of the whole animation (scene)
    vsync:      // the ticker provider
    debugLabel: // a label to be used to identify the controller
            // during debug session
);

在大多数情况下,初始化 AnimationController 时不会设计到 value,lowerBound,upperBound和debugLabel。

如何将 AnimationController 绑定到 Ticker 上

为了让动画正常工作,必须将 AnimationController 绑定到 Ticker 上。

通常情况下,你可以生成一个 Ticker 绑定到一个 StatefulWidget 实例上。

class _MyStateWidget extends State<MyStateWidget>
        with SingleTickerProviderStateMixin {
    AnimationController _controller;

    @override
    void initState(){
      super.initState();
      _controller = new AnimationController(
        duration: const Duration(milliseconds: 1000), 
        vsync: this,
      );
    }

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

    ...
}
  • 第 2 行 这行代码告诉 Flutter ,你想要一个单 Ticker,这个 Ticker 链接到了 MyStateWidget 实例上。
  • 8-10行

控制器的初始化。场景(子动画)的总持续时间设置为1000毫秒,并绑定到了 Ticker(vsync:this)。

隐式参数为:lowerBound = 0.0 和 upperBound = 1.0

  • 16行

非常重要,当 MyStateWidget 这个页面的实例销毁时,您需要释放 controller。

TickerProviderStateMixin 还是 SingleTickerProviderStateMixin?
如果你有几个Animation Controller情况下,你想有不同的 Ticker, 只需要将 SingleTickerProviderStateMixin 替换为 TickerProviderStateMixin。

好的,我已经将控制器绑定到了 Ticker 上,但是它是工作的?

正是由于 ticker,每秒钟将会产生大约 60 个 tick,AnimationController 将根据 tick 在给定的时间里,线性的产生在最小值和最大值之间的值。

在这1000毫秒内产生的值的示例如下:

1815f0f0328e8bc3fbba42b5371e5993.png

我们看到值在1000毫秒内从0.0(lowerBound)到1.0(upperBound)变化。生成了51个不同的值。

让我们扩展代码以查看如何使用它。

class _MyStateWidget extends State<MyStateWidget>
        with SingleTickerProviderStateMixin {
    AnimationController _controller;

    @override
    void initState(){
      super.initState();
      _controller = new AnimationController(
        duration: const Duration(milliseconds: 1000), 
        vsync: this,
      );
      _controller.addListener((){
          setState((){});
      });
      _controller.forward();
    }

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

    @override
    Widget build(BuildContext context){
        final int percent = (_controller.value * 100.0).round();
        return new Scaffold(
            body: new Container(
                child: new Center(
                    child: new Text('$percent%'),
                ),
            ),
        );
    }
}
  • 12 行 此行告诉控制器,每次其值更改时,我们都需要重建Widget(通过setState())
  • 第15行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值