您好,登錄后才能下訂單哦!
這篇文章主要介紹“Flutter怎么使用AnimatedBuilder實現動效復用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter怎么使用AnimatedBuilder實現動效復用”文章能幫助大家解決問題。
我們之前講述了動畫構建的兩種方式,Animation
和 AnimationWidget
,這兩種構建動畫都是將組件和動畫一起完成的。有些時候,我們只是想動效復用,而不關心組件構建,這個時候就可以使用 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: 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(); } }
復用的話也很容易了,比如我們將一個圓形和一個矩形組件傳過去,一樣可以復用這個動畫效果。
關于“Flutter怎么使用AnimatedBuilder實現動效復用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。