欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter Component動畫的顯和隱最佳實踐

 更新時間:2023年03月02日 16:07:43   作者:xuyisheng  
這篇文章主要為大家介紹了Flutter Component動畫的顯和隱最佳實踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

動畫選擇決策樹

Flutter中包含大量的動畫組件和自定義動畫方式,所以,在合適的場景下選擇合適的動畫實現(xiàn)方式就成了決定代碼質(zhì)量好壞的一個重要因素。

Flutter中的動畫從廣義上來講可以分為兩類,一類是基于繪制的動畫(Drawing-based animations),另一類是基于代碼的動畫(Code-based animations)。

下面這個決策樹,是Flutter動畫選擇的總綱,這里梳理了不同的動畫的作用場景和功能,我們來看下它具體的實現(xiàn)。

首先,我們需要區(qū)分是使用CustomPainter,或者是使用Lottie、Flare這種第三方庫,這一類的動畫很容易區(qū)分——如果你第一感覺,這個動畫我做不了,那它大概率就是了。

接下來,就是區(qū)分是使用「顯示動畫」還是「隱式動畫」。

簡單的說,它們的區(qū)別如下:

  • 隱式動畫:不用循環(huán)播放、不用隨時中斷、不用多個動畫協(xié)同,它實現(xiàn)的是一種狀態(tài)到另一種狀態(tài)的改變
  • 顯示動畫:需要自己控制動畫過程

最后,就是看現(xiàn)有組件是否滿足需求,如果不行,那么就需要自定義相應(yīng)的動畫。

這就是整個動畫決策樹的執(zhí)行過程。它們的開發(fā)難度,如下所示。

下面我們就具體來分析下不同的動畫實現(xiàn)。本文首先介紹顯示動畫和隱式動畫。

Implicit Animations——隱式動畫

在Flutter中,很多常用組件都有其自帶的隱式動畫版本,例如下圖所示的這些組件。

這些組件在Flutter中被稱之為隱式動畫Widget,下面以AnimatedContainer為例,來看下Implicit Animations的使用。

隱式動畫有一個特點,那就是它們都是以「Animated」開頭。

基本使用

AnimatedContainer的使用非常簡單,甚至和普通的Container沒有太大的區(qū)別,代碼如下所示。

AnimatedContainer(
  margin: EdgeInsets.only(top: 20),
  width: size,
  height: size,
  decoration: BoxDecoration(
    color: color,
    borderRadius: BorderRadius.circular(radius),
  ),
  curve: Curves.easeIn,
  duration: Duration(milliseconds: 300),
),

當(dāng)通過setState函數(shù)改變AnimatedContainer中的屬性時,AnimatedContainer會經(jīng)過一段動畫效果,然后再完成相應(yīng)的改變。在隱式動畫中,你依然可以定義Curve和Duration等參數(shù),但是你無法控制動畫,即動畫的執(zhí)行和結(jié)束,是由屬性改變來驅(qū)動的。

使用場景

Implicit Animations可以非常方便的使Widget具有動畫效果而不需要寫很多額外的動畫代碼,結(jié)合FutureBuilder或者StreamBuilder,甚至不用寫setState,下面這個例子就演示了如何將Implicit Animations和FutureBuilder結(jié)合起來使用,代碼如下所示。

FutureBuilder(
  future: future,
  builder: (context, snapshot) {
    var width = .0;
    switch (snapshot.connectionState) {
      case ConnectionState.none:
      case ConnectionState.waiting:
      case ConnectionState.active:
        width = .0;
        break;
      case ConnectionState.done:
        width = 100.0;
        break;
    }
    return AnimatedContainer(
      width: width,
      duration: Duration(seconds: 1),
      curve: Curves.easeIn,
      child: Image.asset('images/logo.png'),
    );
  },
),

通過FutureBuilder的各種狀態(tài)回調(diào),就可以設(shè)置不同的Widget,并在FutureBuilder完成并顯示正常的Widget時,產(chǎn)生一個動畫效果,而不是非常生硬的出現(xiàn)。

TweenAnimationBuilder

TweenAnimationBuilder是自定義隱式動畫的方式,借助它,你可以給一個指定的Widget作用一個動畫效果,一個簡單的示例代碼如下所示。

TweenAnimationBuilder(
  tween: Tween<double>(begin: 0, end: 48),
  onEnd: (){}
  duration: Duration(seconds: 1),
  builder: (BuildContext context, double size, Widget child) {
    return IconButton(
      iconSize: size,
      color: Colors.blue,
      icon: child,
    );
  },
  child: Icon(Icons.aspect_ratio),
)

借助TweenAnimationBuilder,就可以將一個指定的Tween作用于builder中的Widget,builder中的第二個參數(shù),就是Tween所指定的參數(shù)的類型,通過TweenAnimationBuilder,就可以在Widget參數(shù)變化的時候產(chǎn)生動畫效果。

TweenAnimationBuilder的builder中如果有不變的Child Widget,可以放在TweenAnimationBuilder的child屬性中,因為builder在產(chǎn)生動畫時會重建,所有不變的Widget,都可以放在TweenAnimationBuilder的child中,再通過builder的第三個參數(shù)來傳遞這個Widget,以避免重建。

通常我們在開發(fā)中,會借助Transform來完成動畫效果,在builder中,根據(jù)Tween返回的數(shù)值,使用不同的Transform來修改動畫狀態(tài)。

TweenAnimationBuilder中的begin,只在第一次使用,后面更新時,只看end的值,例如10-30,修改end為50,實際變化是30-50。如果不傳begin,那么默認(rèn)和end相等。

Explicit Animations——顯示動畫

與隱式動畫不同,顯示動畫給了開發(fā)者對動畫過程的完全掌控,開發(fā)者可以根據(jù)自己的需要來控制動畫,F(xiàn)lutter中內(nèi)置了很多顯示動畫,如下所示。

顯示動畫也有一個很明顯的特點,那就是它們都以「Transition」結(jié)尾。

基本使用

以RotationTransition為例,下面來演示下如何使用Flutter中的顯示動畫。

顯示動畫是通過AnimationController來進行驅(qū)動的,所以,使用顯示動畫的第一步,就是需要創(chuàng)建AnimationController。有了AnimationController之后,就可以通過控制AnimationController的狀態(tài)來控制動畫的驅(qū)動過程,整個代碼如下所示。

AnimationController controller;
@override
void initState() {
  super.initState();
  controller = AnimationController(vsync: this, duration: Duration(seconds: 2))..repeat();
}
@override
void dispose() {
  controller.dispose();
  super.dispose();
}
@override
Widget build(BuildContext context) {
  return Center(
    child: GestureDetector(
      onTap: () {
        if (controller.isAnimating) {
          controller.stop();
        } else {
          controller.repeat();
        }
      },
      child: RotationTransition(
        turns: controller,
        child: FlutterLogo(
          size: 100,
        ),
      ),
    ),
  );
}

與隱式動畫相比,顯式動畫通過AnimationController來獲取動畫的行進狀態(tài)和參數(shù),從而讓調(diào)用者能夠控制動畫的行進過程。

顯式動畫可以實現(xiàn)隱式動畫的所有功能,但是比隱式動畫多了管理動畫生命周期的工作

當(dāng)Flutter內(nèi)置顯示動畫不能滿足開發(fā)者的需求時,F(xiàn)lutter提供了AnimatedBuilder和AnimatedWidget來讓開發(fā)者對顯示動畫進行自定義。

AnimatedWidget

前面提到的都是Flutter中使用動畫的最基本方式,但實際上,F(xiàn)lutter提供了很多關(guān)于動畫的封裝組件,可以讓開發(fā)者更加方便的使用動畫,這就是AnimatedWidget。AnimatedWidget也有很多實現(xiàn)類,如圖所示。

AnimatedWidget是實現(xiàn)自定義顯示動畫的另一種方式,它可以將一些動畫的邏輯以Widget的形式封裝起來,從而讓build函數(shù)中的代碼邏輯更加清晰,下面是AnimatedWidget的示例代碼。

@override
Widget build(BuildContext context) {
  return Stack(
    children: <Widget>[
      AnimWidget(animation: controller),
      Center(child: FlutterLogo(size: 100)),
    ],
  );
}
class AnimWidget extends AnimatedWidget {
  const AnimWidget({
    Key? key,
    required Animation<double> animation,
  }) : super(key: key, listenable: animation);
  @override
  Widget build(BuildContext context) {
    Animation<double> animation = listenable as Animation<double>;
    return Container(
      decoration: BoxDecoration(
        gradient: RadialGradient(
          colors: const [Colors.red, Colors.transparent],
          stops: [0, animation.value],
        ),
      ),
    );
  }
}

那么這種方式和之前直接使用AnimationController和Tween有什么區(qū)別呢?細(xì)心的讀者可能已經(jīng)發(fā)現(xiàn)了,AnimatedWidget不需要自己去監(jiān)聽動畫的回調(diào),也不需要通過setState來刷新動畫,這些操作,AnimatedWidget已經(jīng)封裝好了,這就是AnimatedWidget的作用。

AnimatedBuilder

AnimatedBuilder是一個特殊的AnimatedWidget,它可以直接指定一個動畫作用于Widget上,而不需要重新創(chuàng)建一個自定義的AnimatedWidget,它可以幫助開發(fā)者處理動畫的監(jiān)聽,當(dāng)一個Widget Tree中有一些需要動畫的Widget,也有一些不需要動畫的Widget時,用AnimatedBuilder可以很方便的避免非動畫Widget的重繪,所以說,AnimatedBuilder可以更加方便的給一個Widget增加動畫效果。

AnimatedBuilder與其它的顯示動畫一樣,也是通過AnimationController驅(qū)動的,借助AnimatedBuilder,開發(fā)者可以根據(jù)需要,自己創(chuàng)建Animation并控制它,下面的代碼演示了如何通過控制RadialGradient的stop屬性來控制RadialGradient的顯示大小,從而形成動畫效果,代碼如下所示。

@override
Widget build(BuildContext context) {
  return AnimatedBuilder(
    animation: controller,
    builder: (context, widget) {
      return Stack(
        children: <Widget>[
          Container(
            decoration: BoxDecoration(
              gradient: RadialGradient(
                colors: [Colors.red, Colors.transparent],
                stops: [0, controller.value],
              ),
            ),
          ),
          Center(child: FlutterLogo(size: 100))
        ],
      );
    },
  );
}

上面的代碼演示了如何使用AnimatedBuilder,實際上非常簡單,與使用內(nèi)置的顯示動畫的過程基本一致。

在使用AnimatedBuilder的過程中,需要盡可能多的將需要動畫的部分和不需要動畫的部分區(qū)分開來,這樣可以避免多余的重繪,從而提高動畫性能,例如上面的代碼,可以將FlutterLogo和Stack放置在最外層,這樣只需要讓RadialGradient產(chǎn)生動畫就可以了,代碼如下所示。

@override
Widget build(BuildContext context) {
  return Stack(
    children: <Widget>[
      AnimatedBuilder(
        animation: controller,
        builder: (context, widget) {
          return Container(
            decoration: BoxDecoration(
              gradient: RadialGradient(
                colors: [Colors.red, Colors.transparent],
                stops: [0, controller.value],
              ),
            ),
          );
        },
      ),
      Center(child: FlutterLogo(size: 100))
    ],
  );
}

AnimatedBuilder接收了一個animation,在child中,可以直接使用這個animation的值,其它都和普通的AnimatedWidget類似。

實際上,AnimatedBuilder就是AnimatedWidget的子類,所以在本質(zhì)上,這兩種實現(xiàn)自定義顯示動畫的方式想相同的,開發(fā)者可以根據(jù)自己的喜好來選擇相應(yīng)的方式來創(chuàng)建自己的顯示動畫。

AnimateWidget負(fù)責(zé)組件的抽離,可以看出組件中雜糅了動畫邏輯。而AnimatedBuilder恰好相反,它不在意組件是什么,只是將動畫抽離達到復(fù)用簡單。

Flutter中的顯示動畫和隱式動畫,幾乎可以解決大部分我們平時在開發(fā)中遇到的動畫場景,借助動畫選擇決策樹,我們可以對動畫的選擇了如指掌,剩下的工作,就是對動畫進行拆解,分而治之。

以上就是Flutter Component動畫的顯和隱最佳實踐的詳細(xì)內(nèi)容,更多關(guān)于Flutter Component動畫顯隱的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android開發(fā)之自定義刮刮卡實現(xiàn)代碼

    Android開發(fā)之自定義刮刮卡實現(xiàn)代碼

    本篇文章主要介紹了Android開發(fā)之自定義刮刮卡實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 詳解Android MacAddress 適配心得

    詳解Android MacAddress 適配心得

    本篇文章主要介紹了詳解Android MacAddress 適配心得,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Android開發(fā)手冊自定義Switch開關(guān)按鈕控件

    Android開發(fā)手冊自定義Switch開關(guān)按鈕控件

    這篇文章主要為大家介紹了Android開發(fā)手冊自定義Switch開關(guān)按鈕控件的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Android自定義Animation實現(xiàn)View搖擺效果

    Android自定義Animation實現(xiàn)View搖擺效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義Animation實現(xiàn)View搖擺效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 基于Android實現(xiàn)一個常用的布局吸頂效果

    基于Android實現(xiàn)一個常用的布局吸頂效果

    這篇文章給大家介紹一個布局吸頂效果,一般出現(xiàn)在內(nèi)容較長頁面還嵌套著分類頁面的情況,比如電商的詳情頁嵌套分類,在頁面滑動到tab的時候我們希望tab還能保留在頁面頂部而不被頂上去,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-09-09
  • Android ScrollView無法填充滿屏幕的解決辦法

    Android ScrollView無法填充滿屏幕的解決辦法

    這篇文章主要介紹了Android ScrollView無法填充滿屏幕的解決辦法的相關(guān)資料,這里提供實例和解決辦法,需要的朋友可以參考下
    2017-07-07
  • Flutter倒計時/計時器的實現(xiàn)代碼

    Flutter倒計時/計時器的實現(xiàn)代碼

    這篇文章主要介紹了Flutter倒計時/計時器的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • android使用service和activity獲取屏幕尺寸的方法

    android使用service和activity獲取屏幕尺寸的方法

    這篇文章主要介紹了android使用service和activity獲取屏幕尺寸的方法,實例分析了基于service和activity兩種方法獲取屏幕尺寸的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下
    2015-08-08
  • Flutter圖片與文件選擇器使用實例

    Flutter圖片與文件選擇器使用實例

    這篇文章主要為大家介紹了Flutter圖片與文件選擇器使用實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Android開發(fā)筆記之:Dialog的使用詳解

    Android開發(fā)筆記之:Dialog的使用詳解

    本篇文章是對Android中Dialog的使用進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評論