Flutter學習總結(二十、Flutter的動畫)

Flutter的動畫

一起從0開始學習Flutter!

爲了讓我們的場景切換更加流暢和一些元素更能抓住用戶的眼球,我們在APP中都會添加多種動畫來裝扮我們的APP,在以往的開發中對於普通的旋轉位移,縮放動畫我們都有一些簡單的處理方式,但是面對複雜的動畫我們都會耗費我們大量的時間來進行計算,我們一起來針對Flutter中的動畫進行學習,看下在Flutter中我們如何處理我們日常使用的動畫。
在Flutter中也爲我們提供了多種動畫示例,我們稍後看下,我們先看下如何不使用這些動畫示例來創建一個我們想要的動畫。
我們首先需要一個動畫的控制單元,在Flutter中AnimationController來充當這個角色,我們先認識一下AnimationController:

AnimationController

AnimationController({
    double value, //給定動畫的初始狀態
    this.duration,//動畫執行的時間間隔,如果沒有設置reverseDuration則返回時的持續時間也是duration指定的時間
    this.reverseDuration,//返回原來狀態的動畫運行時間
    this.debugLabel,//調試的標籤
    this.lowerBound = 0.0,//動畫消失時的值
    this.upperBound = 1.0,//動畫完成時的值
    this.animationBehavior = AnimationBehavior.normal,//如果設置爲Normal如果設置的disableAnimations爲True則不會浪費時間,如果設置爲 AnimationBehavior.preserve則會消耗同樣的時間
    @required TickerProvider vsync,//防止屏幕外動畫,消耗不必要的資源
  })

範圍控制我們看到在AnimationController爲我們提供了0-1的控制,但是在實際使用中很多情況是無法滿足我們需求的,我們這時候需要Tween來幫助我們做一個範圍的設定,可以設定動畫變化的範圍。Tween提供了多種樣式的變化,如:IntTween,ColorTween,RectTween等變化的範圍設定。我們簡單來了解下他們,然後可以根據需要在使用的時候進行選擇。

IntTween({ int begin, int end }) : super(begin: begin, end: end);//開始的數值,和結束的數值,都是提供的整數
ColorTween({ Color begin, Color end }) : super(begin: begin, end: end);//開始的顏色,和結束的顏色,提供的是顏色值

我們把他們結合起來看可以做些什麼:

	controller = AnimationController(
        duration: Duration(milliseconds: 1000), vsync: this);//創建一個動畫的控制器
    Tween tween = Tween<double>(begin: 100.0, end: 400.0);//創建一個動畫調整大小的限定器
    animation = tween.animate(controller);//將限定器與控制器進行綁定,就可以得到一個Animation對象
    animation.addListener(() {//當屏幕上每一幀變化的時候都會在這裏進行刷新通知,每次刷新都調用我們build方法重繪當前控制的元素
      setState(() {});
    });
    controller.forward();//開始執行動畫

如果我們想要監聽動畫的開始和結束需要給animation添加狀態監聽:

	animation.addStatusListener((status) {
      if(status == AnimationStatus.completed){//如果當前狀態是已經完成了動畫則往下執行
        controller.reverse(from:1.0);//將動畫反向執行一遍
      }
    });

有了動畫的控制我們只需要根據返回的狀態值,控制build裏面的元素顯示就可以了,比如我們控制Flutter圖標的一個放大動畫:

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10.0),
        height: animation.value,//這裏根據返回的限定值進行刷新,將logo顯示爲指定的大小
        width: animation.value,//這裏根據返回的限定值進行刷新,將logo顯示爲指定的大小
        child: FlutterLogo(),顯示的Flutter圖標的組件
      ),
    );
  }

其他的動畫比如位移和旋轉我們可以控制margin和transform的設置,具體的屬性設置可以參照之前我們介紹容器時的參數說明。
這樣雖然能幫助我們實現動畫,如果我們需要重複利用這個動畫則需要實現多處,我們這時候可以使用AnimatedWidget來幫助我們做一些簡化,Flutter爲我們提供了一些AnimatedWidget的示例,比如FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition。這些是已經幫我們做好的了動畫模式。我們幫上面的例子通過AnimatedWidget來改造一下。

class ImageAnimationWidget extends AnimatedWidget {//創建一個ImageAnimationWidget繼承自AnimatedWidget來實現動畫

  ImageAnimationWidget({Key key, Animation<double> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10.0),
        height: animation.value,
        width: animation.value,
        child: FlutterLogo(),
      ),
    );
  }
}

這塊的代碼就是我們剛剛State裏的build代碼,我們把動畫部分提取了出來,這樣我們在以後需要多個該動畫時直接引用即可,原來的build代碼,現在已經被替換爲了:

@override
  Widget build(BuildContext context) {
    return ImageAnimationWidget(animation: animation,);
  }

還是上面的例子,如果我們想要使用Flutter爲我們提供的示例來實現怎麼做呢:

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(scale: animation,child: FlutterLogo(),);
  }

就是把State裏的build方法替換爲了ScaleTransition,然後我們需要修改animation中的Tween的開始結束大小,方便了很多,其他的動畫我們可以自己進行實驗一下。

通過本篇我們學習了一些簡單的動畫,Flutter的基礎學習也告一段落,接下來需要開一個新的專題,一起學習一個項目的0開始。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章