flutter 动画json_Flutter-动画-实践篇

本文深入介绍了Flutter中的动画应用,包括 AnimatedWidget 的使用,如何自定义 AnimatedWidget 和 AnimatedBuilder,以及展示了位移、旋转、缩放等多种动画示例。此外,还探讨了第三方动画库 Lottie 和 Flare 在Flutter中的实现。
摘要由CSDN通过智能技术生成

一、了解AnimatedWidget

通常我们给一个Widget添加动画的时候都需要监听Animation的addListener()方法,并在这个方法里面不停的调用setState()方法通知Weight进行重绘。

AnimatedWidget是Flutter封装的用于执行动画的助手类。使用它可以使我们创建一个可重用动画的Widget。而且我们也不必关心Weight在什么时候需要重绘,因为AnimatedWidget中会自动调用addListener()和setState()。

AnimatedWidget实际上是一个StatefulWidget,它里面是定义了一套Widget并由外部将执行的动画传进来,然后根据Animation的value使各个Widget做出相应的改变。

Flutter封装了很多AnimatedWidget的助手类。SlideTransition、AlignTransition、PositionedTransition、RelativePositionedTransition等等。

//自定义AnimatedWidget

class CustomAnimatedWidget extendsAnimatedWidget {

CustomAnimatedWidget({Key key, Animationanimation})

:super(key: key, listenable: animation);

Widget build(BuildContext context) {final Animation custom =animation;return newCenter(

child:newContainer(

height: animation.value,

width: animation.value,

child:newContainer(),

),

);

}

}//使用CustomAnimatedWidget

class CustomApp extendsStatefulWidget {

_CustomAppState createState()=> new_CustomAppState();

}class _CustomAppState extends Statewith SingleTickerProviderStateMixin {

AnimationController controller;

Animationanimation;

initState() {super.initState();

controller= newAnimationController(

duration:const Duration(milliseconds: 5000), vsync: this);

animation= new Tween(begin: 0.0, end: 100.0).animate(controller);

controller.forward();

}

Widget build(BuildContext context) {return newCustomAnimatedWidget(animation: animation);

}

dispose() {

controller.dispose();super.dispose();

}

}

View Code

二、了解AnimatedBuilder

AnimatedBuilder相比较AnimatedWidget来说更加纯粹。它不知道如何渲染Widget,也不会管理Animatiion。个人感觉AnimatedWidget是一个执行具体动画的控件,而AnimatedBuilder则是一个执行特定动画的容器。

Flutter中也创建了很多基于AnimatedBuilder的控件。例如:BottomSheet、 PopupMenu、ProgressIndicator、RefreshIndicator、Scaffold、SnackBar、TabBar、TextField。

//自定义CustomAnimatedBuilder

class CustomAnimatedBuilder extendsStatelessWidget {

GrowTransition({this.child, this.animation});finalWidget child;final Animationanimation;

Widget build(BuildContext context) {return newCenter(

child:newAnimatedBuilder(

animation: animation,

builder: (BuildContext context, Widget child) {return newContainer(

height: animation.value, width: animation.value, child: child);

},

child: child),

);

}

}//使用CustomAnimatedBuilder

class CustomApp extendsStatefulWidget {

_CustomAppState createState()=> new_CustomAppState();

}class _CustomAppState extends Statewith TickerProviderStateMixin {

Animation animation;

AnimationController controller;

initState() {super.initState();

controller= newAnimationController(

duration:const Duration(milliseconds: 1000), vsync: this);final CurvedAnimation curve =

newCurvedAnimation(parent: controller, curve: Curves.easeIn);

animation= new Tween(begin: 0.0, end: 100.0).animate(curve);

controller.forward();

}

Widget build(BuildContext context) {return newCustomAnimatedBuilder(child: ‘自己的view’, animation: animation);

}

dispose() {

controller.dispose();super.dispose();

}

}

View Code

三、动画示例

1、位移动画

只要Widget能在一定的时间内按照一定的规则位移一定的距离,那边是产生了位移动画。可以通过改变Widget本身的margin,也可以通过改变父容器的padding,也可以通过SlideTransition的Offset产生位移,也可使用Matrix4的transform产生移动(Matrix4解释和使用)。下面看示例:

//位移动画 copy 代码可以直接使用

import 'package:flutter/material.dart';class TransferAnim extendsStatefulWidget {

@override

_TransferAnimState createState()=>_TransferAnimState();

}//ignore: slash_for_doc_comments/*** 这个实现 实际上是改变 父容器的padding/margin完成的*/

class _TransferAnimState extends Statewith SingleTickerProviderStateMixin {

AnimationController _controller;

Animationanim;

AnimationslideTransition;

@overridevoidinitState() {super.initState();

_initAnim();

}

@override

Widget build(BuildContext context) {returnScaffold(

appBar: AppBar(

centerTitle:true,

title: Text("位移动画"),

),

body: Column(

children:[

Expanded(

child: Container(

padding: anim.value,

child: Center(

child: Container(

width:100,

height:50,

margin: ,

color: Colors.amber,

child: Center(

child: Text("位移动画"),

),

),

),

),

),

Expanded(

child: Container(

child: Center(

child: SlideTransition(

position: slideTransition,

child: Container(

width:100,

height:50,

color: Colors.amber,

child: Center(

child: Text("位移动画"),

),

),

),

),

),

),

],

),

);

}void_initAnim() {

_controller=AnimationController(

vsync:this,

duration: Duration(

seconds:3,

),

);

anim= newEdgeInsetsTween(

begin: EdgeInsets.only(left:0, top: 0),

end: EdgeInsets.only(left:100, top: 150),

).animate(_controller);//Offset 这里解释一下,是相对于自己移动的比例倍数

slideTransition = Tween(

begin: Offset(0, 0),

end: Offset(0, 2),

).animate(_controller);

anim.addListener(() {

setState(() {});

});

anim.addStatusListener((status) {

debugPrint('fanlei => $status');switch(status) {caseAnimationStatus.dismissed:

_controller?.forward();break;caseAnimationStatus.forward:break;caseAnimationStatus.reverse:break;caseAnimationStatus.completed:

_controller?.reverse();break;

}

});

_controller?.forward();

}

@overridevoiddispose() {

_controller?.dispose();super.dispose();

}

}

View Code

2、旋转动画

旋转动画就是一个Weight以某个点或者某个坐标轴旋转。可以使用Container()的transform(接受Matrix4)属性,也可以使用RotationTransition()执行旋转动画。下面看示例:

import 'package:flutter/material.dart';class RotateAnim extendsStatefulWidget {

@override

_RotateAnimState createState()=>_RotateAnimState();

}//ignore: slash_for_doc_comments

class _RotateAnimState extends Statewith SingleTickerProviderStateMixin {

AnimationController _controller;

Animationanim;

AnimationdoubleAnim;

@overridevoidinitState() {super.initState();

_initAnim();

}

@override

Widget build(BuildContext context) {returnScaffold(

appBar: AppBar(

centerTitle:true,

title: Text("旋转动画"),

),

body: Container(

child: Column(

children:[

Expanded(

child: Center(

child: Container(

transform: anim.value,

width:200,

height:50,

color: Colors.amber,

child: Center(

child: Text("旋转动画矩阵变换"),

),

),

),

),

Expanded(

child: Center(

child: RotationTransition(

turns: doubleAnim,

child: Container(

width:200,

height:50,

color: Colors.greenAccent,

child: Center(

child: Text("旋转动画Rotation"),

),

),

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值