中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter怎么使用AnimatedBuilder實現動效復用

發布時間:2022-04-02 13:44:23 來源:億速云 閱讀:235 作者:iii 欄目:開發技術

這篇文章主要介紹“Flutter怎么使用AnimatedBuilder實現動效復用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter怎么使用AnimatedBuilder實現動效復用”文章能幫助大家解決問題。

    前言

    我們之前講述了動畫構建的兩種方式,Animation 和 AnimationWidget,這兩種構建動畫都是將組件和動畫一起完成的。有些時候,我們只是想動效復用,而不關心組件構建,這個時候就可以使用 AnimatedBuilder 了。

    AnimatedBuilder 介紹

    根據官方文檔說明,AnimatedBuilder 的使用要點如下:

    • An AnimatedBuilder understands how to render the transition. —— AnimatedBuilder 知道如何渲染轉場動效。

    • An AnimatedBuilder doesn’t know how to render the widget, nor does it manage the Animation object. —— AnimatedBuilder 不知道(或者準確說不應)如何渲染組件,也不管理組件對象。

    • Use AnimatedBuilder to describe an animation as part of a build method for another widget. If you simply want to define a widget with a reusable animation, use an AnimatedWidget. —— 使用 AnimatedBuilder 作為其他組件的動效描述。如果只是想復用一個帶有動效的組件,那么應該使用 AnimatedWidget。這個可以看我們之前關于 AnimatedWidget 的介紹:Flutter 入門與實戰(九十四):讓你的組件擁有三維動效

    • Examples of AnimatedBuilders in the Flutter API: BottomSheetExpansionTilePopupMenuProgressIndicatorRefreshIndicatorScaffoldSnackBarTabBarTextField. —— 在 Flutter 中,有很多組件使用 AnimatedBuilder 構建動效。

    這段話的核心要點就是 AnimatedBuilder 應該只負責動畫效果的管理,而不應該管理組件構建。如果混在一起使用,就失去設計者的初衷了。這就好比我們的狀態管理和界面一樣,一個負責業務邏輯,一個負責界面渲染,從而實現解耦和復用。這個AnimatedBuilder就是專門復制動效管理的,并且應當努力實現復用。AnimatedBuilder的定義如下:

    const AnimatedBuilder({
        Key? key,
        required Listenable animation,
        required this.builder,
        this.child,
      }) : assert(animation != null),
           assert(builder != null),
           super(key: key, listenable: animation);

    其中關鍵的參數是builderbuilder 用于構建組件的轉變動作,在 builder 里可以對要渲染的子組件進行轉變操作,然后返回變換后的組件。builder 的定義如下,其中 child 實際就是 AnimatedBuilder 的 child 參數,可以根據需要是否使用。

    Widget Function(BuildContext context, Widget? child)

    Transform 組件介紹

    在 Flutter 中,提供了一個專門用于對子組件進行轉換操作的,定義如下:

    const Transform({
        Key? key,
        required this.transform,
        this.origin,
        this.alignment,
        this.transformHitTests = true,
        Widget? child,
      }) : assert(transform != null),
           super(key: key, child: child);

    這里的參數說明如下:

    • transform 是一個Matrix4 對象,用于定義三維空間的變換操作。

    • origin 是一個坐標偏移量,實際會加入到 Matrix4 的 translation(平移)中。

    • alignment:即轉變進行的參考方位。

    • child:被轉換的子組件。

    我們可以通過 Transform,實現 AnimatedBuilder 的動效管理,也就是在 AnimatedBuilder 中,通過構建 Transform 對象實現動效。

    應用

    基本概念講清楚了(敲黑板:很多時候大家都是直接簡單看一下文檔就開始用,甚至干脆復制示例代碼就上,結果很可能會用得不對),可以開始擼代碼了。我們來實現下面的動效。

    Flutter怎么使用AnimatedBuilder實現動效復用

    這里其實是兩個組件,通過 AnimatedBuilder 做了動效轉換。在動效的一半時間是文字“點擊按鈕變出小姐姐”,之后的一半將組件更換為了小姐姐的圖片了。使用AnimatedBuilder 的實現代碼如下:

    class RotationSwitchAnimatedBuilder extends StatelessWidget {
      final Widget child1, child2;
      final Animation<double> animation;
      const RotationSwitchAnimatedBuilder(
          {Key? key,
          required this.animation,
          required this.child1,
          required this.child2})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: animation,
          builder: (context, child) {
            if (animation.value < 0.5) {
              return Transform(
                transform: Matrix4.identity()
                  ..rotateZ(animation.value * pi)
                  ..setEntry(0, 1, -0.003),
                alignment: Alignment.center,
                child: child1,
              );
            } else {
              return Transform(
                transform: Matrix4.identity()
                  ..rotateZ(pi)
                  ..rotateZ(animation.value * pi)
                  ..setEntry(1, 0, 0.003),
                child: child2,
                alignment: Alignment.center,
              );
            }
          },
        );
      }
    }

    注意第2個組件多轉了180度,是未來保證停止后正好旋轉360度,以免圖片倒過來。另外就是這里的 child1和 child2也可以修改為使用 WidgetBuilder 函數來在需要的時候再構建組件。使用這個RotationSwitchAnimatedBuilder的組件就十分簡單了,將需要操作的兩個組件作為參數傳過來,然后控制 Animation 對象來刷新界面就好了,對應的代碼如下:

    class AnimatedBuilderDemo extends StatefulWidget {
      const AnimatedBuilderDemo({Key? key}) : super(key: key);
    
      @override
      _AnimatedBuilderDemoState createState() => _AnimatedBuilderDemoState();
    }
    
    class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>
        with SingleTickerProviderStateMixin {
      late Animation<double> animation;
      late AnimationController controller;
    
      @override
      void initState() {
        super.initState();
        controller =
            AnimationController(duration: const Duration(seconds: 1), vsync: this);
        animation = Tween<double>(begin: 0, end: 1.0).animate(controller);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('AnimatedBuilder 動畫'),
          ),
          body: RotationSwitchAnimatedBuilder(
            animation: animation,
            child1: Center(
              child: Container(
                padding: EdgeInsets.all(10),
                margin: EdgeInsets.all(10),
                constraints: BoxConstraints(minWidth: double.infinity),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(4.0),
                  gradient: LinearGradient(
                    colors: [
                      Colors.orange,
                      Colors.green,
                    ],
                  ),
                ),
                child: Text(
                  '點擊按鈕變出小姐姐',
                  style: TextStyle(
                    fontSize: 20,
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
            ),
            child2: Center(
              child: Image.asset('images/beauty.jpeg'),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.play_arrow, color: Colors.white),
            onPressed: () {
              if (controller.status == AnimationStatus.completed) {
                controller.reverse();
              } else {
                controller.forward();
              }
            },
          ),
        );
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    }

    復用的話也很容易了,比如我們將一個圓形和一個矩形組件傳過去,一樣可以復用這個動畫效果。

    Flutter怎么使用AnimatedBuilder實現動效復用

    關于“Flutter怎么使用AnimatedBuilder實現動效復用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    天气| 二连浩特市| 北海市| 金乡县| 乌鲁木齐市| 肇州县| 绥芬河市| 娄底市| 来凤县| 江山市| 高碑店市| 青神县| 伊川县| 隆德县| 荣昌县| 舟山市| 鹤山市| 陵水| 葫芦岛市| 靖安县| 岚皋县| 壶关县| 开封县| 梧州市| 德阳市| 安龙县| 汉沽区| 探索| 股票| 碌曲县| 天全县| 蓬溪县| 铅山县| 沁水县| 侯马市| 壶关县| 申扎县| 铜陵市| 安国市| 竹溪县| 故城县|