1.?AnimationController
動(dòng)畫控制器,控制動(dòng)畫的啟動(dòng)山析、停止奶是,還可以獲取動(dòng)畫的運(yùn)行狀態(tài)
class _AnimationDemoState extends State<AnimationDemo>?with SingleTickerProviderStateMixin
創(chuàng)建一個(gè)AnimationController
AnimationController(vsync:this, duration:Duration(seconds:3))
vsync:本身Widget(單個(gè) AnimationController 的時(shí)候使用?SingleTickerProviderStateMixin瑞佩,多個(gè) AnimationController 使用?TickerProviderStateMixin)聚磺,?存在vsync時(shí)會(huì)防止屏幕外動(dòng)畫消耗不必要的資源
動(dòng)畫的狀態(tài)分為四種:
dismissed:動(dòng)畫停止在開始處。
forward:動(dòng)畫正在從開始處運(yùn)行到結(jié)束處(正向運(yùn)行)钉凌。
reverse:動(dòng)畫正在從結(jié)束處運(yùn)行到開始處(反向運(yùn)行)咧最。
completed:動(dòng)畫停止在結(jié)束處。
動(dòng)畫的控制方法:
forward:正向執(zhí)行動(dòng)畫御雕。
reverse:反向執(zhí)行動(dòng)畫矢沿。
repeat:反復(fù)執(zhí)行動(dòng)畫。
reset:重置動(dòng)畫酸纲。
使用示例
監(jiān)聽頁面狀態(tài)變化
_animationController.addStatusListener((status) {
????if (status == AnimationStatus.completed) {
????????_animationController.reset();
????????setState(() {
????????????_islike =false;
????????});????????
????}
});
_animationController?.addListener(() {
? ? // 頁面刷新
????setState(() {
????});
});
_animationController.value 默認(rèn)值值是從0-1的
AnimationController銷毀
void dispose() {
????super.dispose();
????_animationController?.dispose();
}
2.Tween 和 Curve
把從 0 -> 1 轉(zhuǎn)換為 藍(lán)色 -> 紅色 行為稱之為?Tween(映射)捣鲸,
Curve?Tween的值之間變化的規(guī)律(線性...)
系統(tǒng)提供的 Tween(選中類Tween,快捷鍵Ctrol+h,查看類的繼承關(guān)系)
系統(tǒng)已經(jīng)提供了38種常用到動(dòng)畫曲線?Curves.bounceIn
使用示例
ColorTween(begin: Colors.blue, end: Colors.red)
????.chain(CurveTween(curve: Curves.bounceIn))
????.animate(_animationController!)
另外一種使用方式
_animationController?.drive(CurveTween(curve: Curves.linear))
.drive(Tween(begin:100.0, end:200.0));
自定義curve
class MyCurve extends Curve {
? ????@override
????? double transformInternal(double t) {
? ? ????return t; //線性執(zhí)行
????? }
}?
需要繼承 Curve 重寫 transformInternal 方法
3.組合動(dòng)畫
實(shí)現(xiàn) 40%,widget由 100 -> 200, 20% widget大小保持不變闽坡, 40%widget 背景色由藍(lán)色-> 紅色
_tweenSequenceAnimation =TweenSequence([
????TweenSequenceItem(tween:Tween(begin:100.0, end:200.0), weight:40),
????TweenSequenceItem(tween:ConstantTween(200.0), weight:20),
????TweenSequenceItem(tween:ColorTween(begin: Colors.blue, end: Colors.red), weight:40),
]).animate(_animationController!);
TweenSequence 值使用
width:_tweenSequenceAnimation?.value is double ?_tweenSequenceAnimation?.value :200,
height:_tweenSequenceAnimation?.value is double ?_tweenSequenceAnimation?.value :200,
color:_tweenSequenceAnimation?.value is Color ?_tweenSequenceAnimation?.value : Colors.blue
4.隱性動(dòng)畫和顯性動(dòng)畫
顯性動(dòng)畫:動(dòng)畫組件只封裝 setState?方法
隱性動(dòng)畫:組件封裝了 AnimationController栽惶、Curve、Tween
顯性動(dòng)畫系統(tǒng)的類
? ??
隱性動(dòng)畫系統(tǒng)的類
使用示例 見下面路由動(dòng)畫
5.路由動(dòng)畫
自定義動(dòng)畫 需要實(shí)現(xiàn)PageRouteBuilder
自定義從左往右動(dòng)畫
class LeftToRightPageRouteextends PageRouteBuilder {
????final Widget_newpage;
????LeftToRightPageRoute(this._newpage)
????:super(pageBuilder: (BuildContext context, Animation animation,
????Animation secondaryAnimation) {
????????return _newpage;
? ? ? }, transitionsBuilder: (BuildContext context,
????????????Animation animation,
????????????Animation secondaryAnimation,
????????????Widget child) {
????????????return SlideTransition(
????????????????????position:Tween(begin:Offset(1,0), end:Offset(0,0))
????????????????????.animate(animation),
????????????????????child: child,
????????????);
????????});
}
// 頁面圓形形狀 打開
class CirclePageRouteextends PageRouteBuilder {
????final Widget_newpage;
????CirclePageRoute(this._newpage)
????????:super(pageBuilder: (BuildContext context, Animation animation,
????????????Animation secondaryAnimation) {
????????????????return _newpage;
????????????}, transitionsBuilder: (BuildContext context,
????????????????Animation animation,
????????????????Animation secondaryAnimation,
????????????????Widget child) {
????????????????return AnimatedBuilder(
????????????????????animation: animation,
????????????????????builder: (context, child) {
????????????????????return ClipPath(
????????????????????????????clipper:_CustomClip(animation.value),
? ? ? ? ? ? ? ? ? ? ? ????????child: child,
????????????????????????);
????????????????????},
????????????????child: child,
? ? ? ?????);
????});
}
自定義裁剪形狀
class _CustomClipextends CustomClipper {
final doublevalue;
_CustomClip(this.value);
@override
? Path getClip(Size size) {
????????Path _path =Path();
????????double radius = value * sqrt(size.height * size.height + size.width * size.width);
????????_path.addOval(Rect.fromCircle(center:Offset(size.width,0), radius: radius));
????????return _path;
}
@override
? bool shouldReclip(covariant CustomClipper oldClipper) {
????????return true;
????}
}
6.其他動(dòng)畫
Hero 動(dòng)畫疾嗅,系統(tǒng)提供的動(dòng)畫插件animations: ^1.1.1(使用參考官方文檔)
Flow(
????delegate:CirclePointFlowDelegate(),
????children: [
????????_buildCirclePoint(2,Color(0xFF97B1CE), circleAnimation), // 自定義的組件外厂,circleAnimation Animation????
????],
)
class CirclePointFlowDelegateextends FlowDelegate {
????@override
? ????void paintChildren(FlowPaintingContext context) {
????????????print(context.size);
????????????double radius =30;
????????????double rx = context.size.width /2;
????????????double ry = context.size.height /2;
????????????for (int i =0;i < context.childCount;i++) {
????????????????print(context.getChildSize(i));
????????????????if (i %2 ==0) {
????????????????????double x = rx + (radius) * cos(i *2 * pi / (context.childCount -1));
????????????????????double y = ry + (radius) * sin(i *2 * pi / (context.childCount -1));
????????????????????context.paintChild(i, transform:Matrix4.translationValues(x, y,0));
????????????????}else {
????????????????????double x = rx + (radius ) * cos((i -1) *2 * pi / (context.childCount -1) + 2 * pi / ((context.childCount -1) *3));
????????????????????double y = ry + (radius) * sin((i -1) *2 * pi / (context.childCount -1) + 2 * pi / ((context.childCount -1) *3));
????????????????????context.paintChild(i, transform:Matrix4.translationValues(x, y,0));
????????????????}
????????}
}
@override
? bool shouldRepaint(covariant FlowDelegate oldDelegate) {
????????return true;
????}
}