Flutter封裝組動(dòng)畫混合動(dòng)畫AnimatedGroup示例詳解
一、來源
項(xiàng)目中遇到混合動(dòng)畫的情況,每次實(shí)現(xiàn)都需要生命一堆屬性,讓代碼變得雜亂,難以維護(hù)。
參考 iOS 組動(dòng)畫 CAAimationGroup, 隨花半天時(shí)間封裝一個(gè)混合動(dòng)畫組件 AnimatedGroup。
此組件基于極簡(jiǎn)、高擴(kuò)展、高適用的封裝原則,基本滿足當(dāng)前項(xiàng)目開發(fā)。
二、AnimatedGroup使用示例:
// // AnimatedGroupDemo.dart // flutter_templet_project // // Created by shang on 12/6/21 5:52 PM. // Copyright ? 12/6/21 shang. All rights reserved. // import 'package:flutter/material.dart'; import 'package:flutter_templet_project/basicWidget/animated_group.dart'; class AnimatedGroupDemo extends StatefulWidget { AnimatedGroupDemo({ Key? key, this.title}) : super(key: key); final String? title; @override _AnimatedGroupDemoState createState() => _AnimatedGroupDemoState(); } class _AnimatedGroupDemoState extends State<AnimatedGroupDemo> { GlobalKey<AnimatedGroupState> _globalKey = GlobalKey(); final _animations = <AnimatedGroupItemModel>[ AnimatedGroupItemModel( tween: Tween<double>(begin: .0, end: 300.0,), begin: 0.0, end: 0.6 ), AnimatedGroupItemModel( tween: ColorTween(begin: Colors.green, end: Colors.red,), begin: 0.0, end: 0.6 ), AnimatedGroupItemModel( tween: Tween<EdgeInsets>( begin: const EdgeInsets.only(left: .0), end: const EdgeInsets.only(left: 100.0), ), begin: 0.6, end: 1.0 ), ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title ?? "$widget"), ), body: Center( child: Column( children: [ ElevatedButton( child: Text("start animation"), onPressed: (){ _globalKey.currentState?.palyeAnimations(isRemovedOnCompletion: false); }, ), Container( width: 300, height: 300, child: AnimatedGroup( key: _globalKey, duration: Duration(milliseconds: 2000), animations: _animations, child: Text("AnimatedGroupWidget 混合動(dòng)畫", style: TextStyle(color: Colors.white, backgroundColor: Colors.green),), builder: (BuildContext context, Widget? child, List<Animation<dynamic>> animations) { final aHeight = animations[0]; final aColor = animations[1]; final aPadding = animations[2]; return Stack( children: [ Container( alignment: Alignment.bottomCenter, padding: aPadding.value, child: Container( color: aColor.value, width: 50.0, height: aHeight.value, ), ), Center(child: child!) ], ); }, ), decoration: BoxDecoration( color: Colors.black.withOpacity(0.1), border: Border.all( color: Colors.black.withOpacity(0.5), ) ), ) ], ), ), ); } }
三、AnimatedGroup源碼
// // AnimatedGroupDemo.dart // flutter_templet_project // // Created by shang on 1/19/23 8:21 AM. // Copyright ? 1/19/23 shang. All rights reserved. // import 'package:flutter/material.dart'; /// 混合動(dòng)畫回調(diào)類型 typedef AnimatedGroupBuilder = Widget Function(BuildContext context, Widget? child, List<Animation<dynamic>> animations); class AnimatedGroup extends StatefulWidget { /// 混合動(dòng)畫 AnimatedGroup({ Key? key, required this.animations, required this.builder, this.controller, this.duration = const Duration(milliseconds: 2000), this.child, }) : super(key: key); /// 混合動(dòng)畫數(shù)組 List<AnimatedGroupItemModel> animations; /// 混合動(dòng)畫回調(diào) AnimatedGroupBuilder builder; /// 控制器 AnimationController? controller; /// AnimationController 控制的 duration 屬性 Duration? duration; /// 不需要多次構(gòu)建的部分 Widget? child; @override AnimatedGroupState createState() => AnimatedGroupState(); } /// 混合動(dòng)畫 State class AnimatedGroupState extends State<AnimatedGroup> with TickerProviderStateMixin { AnimationController? _controller; /// 僅限于無法滿足功能時(shí)使用(透?jìng)鲗?duì)象, 方便二次開發(fā)) AnimationController get controller => _controller!; List<Animation<dynamic>> _animations = []; @override void initState() { _controller = widget.controller ?? AnimationController(duration: widget.duration, vsync: this); _animations = widget.animations.map((e) => e.tween.animate(_buildAnim(e.begin, e.end))).toList(); super.initState(); } @override void dispose() { _controller?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller!, child: widget.child, builder: (BuildContext context, Widget? child){ return widget.builder(context, child, _animations); } ); } /// 開始執(zhí)行動(dòng)畫 /// /// isRemovedOnCompletion 是否單程動(dòng)畫 /// /// isReverse 是否逆轉(zhuǎn)動(dòng)畫 palyeAnimations({bool isRemovedOnCompletion = true, bool isReverse = false}) async { try { if (!isReverse) { await _controller?.forward().orCancel; if (!isRemovedOnCompletion) { await _controller?.reverse().orCancel; } } else { await _controller?.reverse().orCancel; if (!isRemovedOnCompletion) { await _controller?.forward().orCancel; } } } on TickerCanceled { // the animation got canceled, probably because we were disposed }; } /// 創(chuàng)建動(dòng)畫對(duì)象 CurvedAnimation _buildAnim(double begin, double end) { return CurvedAnimation( parent: _controller!, curve: Interval( begin, end, curve: Curves.ease, ), ); } } /// 混合動(dòng)畫單個(gè)動(dòng)畫模型 class AnimatedGroupItemModel{ /// 混合動(dòng)畫單個(gè)動(dòng)畫模型 AnimatedGroupItemModel({ required this.tween, required this.begin, required this.end, }); /// 動(dòng)畫 Tween Tween tween; /// 動(dòng)畫開始時(shí)間 (0 - 1.0) double begin; /// 動(dòng)畫結(jié)束時(shí)間 (0 - 1.0) double end; }
最后
代碼復(fù)制到項(xiàng)目中可直接運(yùn)行;
以上就是Flutter封裝組動(dòng)畫混合動(dòng)畫AnimatedGroup示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter封裝AnimatedGroup的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android layoutAnimation詳解及應(yīng)用
這篇文章主要介紹了Android layoutAnimation詳解及應(yīng)用的相關(guān)資料,需要的朋友可以參考下2017-05-05Android 去掉自定義dialog的白色邊框的簡(jiǎn)單方法
這篇文章介紹了Android 去掉自定義dialog的白色邊框,有需要的朋友可以參考一下2013-09-09Android編程實(shí)現(xiàn)泡泡聊天界面實(shí)例詳解(附源碼)
這篇文章主要介紹了Android編程實(shí)現(xiàn)泡泡聊天界面,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android泡泡聊天界面的窗體定義與功能實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11Compose?動(dòng)畫藝術(shù)探索之可見性動(dòng)畫示例詳解
這篇文章主要為大家介紹了Compose?動(dòng)畫藝術(shù)探索之可見性動(dòng)畫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android Studio 超級(jí)簡(jiǎn)單的打包生成apk的方法
本篇文章主要介紹了Android Studio 超級(jí)簡(jiǎn)單的打包生成apk的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10android使用handler ui線程和子線程通訊更新ui示例
這篇文章主要介紹了android使用handler ui線程和子線程通訊更新ui的方法,大家參考使用吧2014-01-01Android?Flutter實(shí)現(xiàn)有趣的頁(yè)面滾動(dòng)效果
Flutter提供了?CustomScrollView?來粘合多個(gè)滑動(dòng)組件,并且可以實(shí)現(xiàn)更有趣的滑動(dòng)效果,本文就來為大家詳細(xì)講講實(shí)現(xiàn)的方法,需要的可以參考一下2022-06-06