成為Flutter動畫大師(一)

CoorChice發表於2019-04-06

目錄傳送門:《Flutter快速上手指南》先導篇

在 Flutter 中,動畫被分為兩大類:Tween animation(補間動畫)Physics-based animation(物理動畫)

  1. Tween animation(補間動畫)

    定義了動畫的 初始狀態終止狀態,在指定的一段時間內完成狀態的過度。

    期間可以以線性和非線性的方式控制過度的速度。

  2. Physics-based animation(物理動畫)

    模擬現實世界物體運動的動畫。比如:自由落體運動、加速度等。

不管是 TweenAnimation 還是 Physics-baseAnimation 最終都是通過計算出一系列的值來修改檢視的屬性,從而讓檢視 "動起來"。

1.一個動畫的例子

class AnimPage2 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _AnimPage2();
  }
}

class _AnimPage2 extends State<AnimPage2> with TickerProviderStateMixin{

  var w = 100.0;
  var h = 100.0;

  Animation<double> animation;
  AnimationController animationController;


  @override
  void initState() {
      super.initState();
      // 建立 AnimationController,用於控制動畫
      // 必須提供動畫時間
      animationController = new AnimationController(vsync: this,duration: Duration(milliseconds: 1500));
      // 建立一個插值器,關聯 AnimationController,返回一個新的 Animation 物件
      animation = Tween<double>(begin: 100.0, end: 100.0*2.0).animate(animationController);

      animationController.addListener((){
        // 當動畫更新時會呼叫
        // 需要在這個函式中,呼叫 setState() 來觸發檢視重新整理
        setState(() {
        });
      });
      // 開始播放動畫
      animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Anim Demo 2'),
      ),
      body: Container(
        alignment: Alignment.center,
        child: SizedBox(
          // 獲取插值器計算出的 value
          // 作為屬性值
          width: animation.value,
          height: animation.value,
          child: Container(
            color: Colors.lightBlue,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    // 動畫使用完成後必需要銷燬
    animationController.dispose();
  }
}
複製程式碼

看看效果:

2.動畫中的核心角色

通過觀察上面的例子,可以看出,在 Flutter 中實現動畫效果需要涉及到的幾個核心角色 ?

  • Animation:動畫物件。

  • AnimationController:繼承自 Animation,但它能控制動畫的播放、停止等。不需要時必須呼叫 dispose() 釋放掉。

  • Animatable:插值器,用於產生動畫過程中一系列的值。

在 Flutter 中,實現動畫的核心是:

  1. 通過 插值器 產生一系列的值;

  2. 在值更新的回撥監聽 addListener() 中,通過 setState() 重新整理檢視;

  3. 插值器 產生的值設定到相應的檢視屬性上。

3.AnimationController

AnimationController 繼承自 Animation

就像它的名字一樣,它是動畫的控制器,能夠控制動畫的播放、停止、釋放等。

3.1 AnimationController 常用屬性

屬性型別說明
durationDuration動畫時長
lowerBounddouble設定動畫開始的最小值
upperBounddouble設定動畫結束的最大值
vsyncTickerProvider用於監聽系統的 Vsync 訊號。當一個 Vsync 資訊發出時,能夠觸發重新整理數值,驅動動畫

3.2 AnimationController 常用函式

  • forward()

    開始播放動畫,呼叫它就沒錯了。

  • stop()

    停止動畫。

  • reset()

    重置動畫。

  • reverse()

    反向播放動畫。必須處於正向動畫播放完成的狀態才有用。

  • dispose()

    釋放動畫佔用資源。

  • fling()

    通過內部的 SpringSimulation 產生一系列值來驅動動畫,其值的產生符合 胡克定律

    此時不需要再設定 duration,設定了也沒用。

    在建立列表滑動動畫時,你可能會用到它。

    這實際上就是一個 Physics-based animation

  • repeat()

    迴圈播放動畫。

  • animateWith()

    通過 Simulation 來產生值驅動動畫。

3.3 交錯動畫-同時播放多個動畫

在 Flutter 中同時播放多個動畫,只需要使用同一個 AnimationController 就行。

var animationController = new AnimationController(vsync: this,duration: Duration(milliseconds: 1500));
var animation1 = Tween<double>(begin: 100.0, end: 100.0*2.0).animate(animationController);
var animation2 = Tween<double>(begin: 0.0, end: 1.0).animate(animationController);

animationController.forward();
複製程式碼

通過同一個 animationController 物件就可以同時控制 animation1animation2 兩個動畫了。

到此,讀者應該已經能建立自己的動畫 Demo 了。

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github


相關文章