<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們之前講述了動畫構建的兩種方式,Animation
和 AnimationWidget
,這兩種構建動畫都是將元件和動畫一起完成的。有些時候,我們只是想動效複用,而不關心元件構建,這個時候就可以使用 AnimatedBuilder
了。
根據官方檔案說明,AnimatedBuilder
的使用要點如下:
AnimatedBuilder
understands how to render the transition. —— AnimatedBuilder 知道如何渲染轉場動效。AnimatedBuilder
doesn’t know how to render the widget, nor does it manage the Animation
object. —— AnimatedBuilder
不知道(或者準確說不應)如何渲染元件,也不管理元件物件。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 入門與實戰(九十四):讓你的元件擁有三維動效BottomSheet
, ExpansionTile
, PopupMenu
, ProgressIndicator
, RefreshIndicator
, Scaffold
, SnackBar
, TabBar
, TextField
. —— 在 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);
其中關鍵的引數是builder
,builder
用於構建元件的轉變動作,在 builder
裡可以對要渲染的子元件進行轉變操作,然後返回變換後的元件。builder
的定義如下,其中 child
實際就是 AnimatedBuilder
的 child
引數,可以根據需要是否使用。
Widget Function(BuildContext context, Widget? child)
在 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
物件實現動效。
基本概念講清楚了(敲黑板:很多時候大家都是直接簡單看一下檔案就開始用,甚至乾脆複製範例程式碼就上,結果很可能會用得不對),可以開始擼程式碼了。我們來實現下面的動效。
這裡其實是兩個元件,通過 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(); } }
複用的話也很容易了,比如我們將一個圓形和一個矩形元件傳過去,一樣可以複用這個動畫效果。
本篇介紹了 AnimatedBuilder
的概念和應用, Flutter 提供 AnimatedBuilder
元件的核心理念是為了建立和管理可複用的動畫效果。在使用的時候,應該將動畫效果和元件構建分離,從而使得AnimatedBuilder
構建的動畫效果可以在需要的時候得到複用。
以上就是Flutter使用AnimatedBuilder實現動效複用的詳細內容,更多關於Flutter動效複用的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45