官方動畫介紹bash
Widget
動起來Animation
原理相似於Android
的屬性動畫,和Widget
分離,在必定時間內生成一系列的值,值能夠是int
,double
,color
或者string
等等,每隔N毫秒,或者N秒鐘獲取到最新的值去替換掉Widget
上的值,同時刷新佈局,若是刷新間隔足夠小就能起到動畫的做用,例如構造一個Widget
,他的width
,height
由動畫來控制,必定時間動態更新值使Widget
產生動效:less
new Container(
margin: new EdgeInsets.symmetric(vertical: 10.0),
height: animation.value,
width: animation.value,
child: new FlutterLogo(),
),
複製代碼
接下來看下如何使用Animation
構建一個動態更新Widget
的簡單場景ide
Animation
類 import 'package:flutter/animation.dart';
StatefulWidget
,建立Animation
的實現類AnimationController
,來構造一個最簡單的屬性動畫,而且應用到Widget
上。class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
// TODO: implement initState
super.initState();
animationController = AnimationController(
vsync: this, duration: Duration(milliseconds: 1000));
animationController.addListener(() {
setState(() {});
});
animationController.forward(); //啓動動畫
}
@override
Widget build(BuildContext context) {
print('tag' + animationController.value.toString());
return Center(
child: Container(
width: animationController.value,
height: animationController.value * 100,
color: Colors.red,
),
);
}
}
複製代碼
能夠看到回調打印的是從0-1的值,要返回其餘類型的數值就須要用到Tween
,Tween
有許多子類例如:佈局
class _TestPageState extends State<TestPage>
with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation animation;
@override
void initState() {
// TODO: implement initState
super.initState();
animationController = AnimationController(
vsync: this, duration: Duration(milliseconds: 1000));
animation = Tween(begin: 0.0,end: 100.0).animate(animationController);
animationController.addListener(() {
setState(() {});
});
animationController.forward(); //啓動動畫
}
@override
Widget build(BuildContext context) {
print('tag' + animationController.value.toString());
return Center(
child: Container(
width: animation.value.toDouble(),
height: animation.value.toDouble() ,
color: Colors.red,
),
);
}
}
複製代碼
AnimatedWidget
來簡化代碼AnimatedWidget
,省去了addListener()
以及setState()
交給AnimatedWidget
處理,感受也沒省掉不少。。class TestContainer extends AnimatedWidget {
TestContainer({Key key,Animation animation})
: super(key: key, listenable: animation);
@override
Widget build(BuildContext context) {
// TODO: implement build
Animation animation = listenable;
return Center(
child: Container(
width: animation.value.toDouble(),
height: animation.value.toDouble() ,
color: Colors.red,
),
);
}
}
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation animation;
@override
void initState() {
// TODO: implement initState
super.initState();
animationController = AnimationController(
vsync: this, duration: Duration(milliseconds: 1000));
animation = Tween(begin: 0.0,end: 100.0).animate(animationController);
animationController.forward(); //啓動動畫
}
@override
Widget build(BuildContext context) {
return TestContainer(animation: animation,);
}
}
複製代碼
AnimatedWidget
相關Api
來再次簡化代碼,例如使用RotationTransition
將Widget
在3秒鐘內旋轉360度class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation animation;
@override
void initState() {
// TODO: implement initState
super.initState();
animationController = AnimationController(
vsync: this, duration: Duration(seconds: 10));
animation = Tween(begin: 0.0, end: 1).animate(animationController);
animationController.forward(); //啓動動畫
}
@override
Widget build(BuildContext context) {
return RotationTransition(turns: animation,
child: Center(
child: Container(color: Colors.red, width: 100, height: 100,)),);
}
}
複製代碼
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
複製代碼
AnimationBuilder
,將控件和動畫的控制過程進行封裝class TestTransition extends StatelessWidget {
TestTransition({this.child, this.animation});
final Widget child;
final Animation<double> animation;
Widget build(BuildContext context) {
return new Center(
child: new AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget child) {
return new Container(
height: animation.value, width: animation.value, child: child);
},
child: child),
);
}
}
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage>
with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation animation;
@override
void initState() {
// TODO: implement initState
super.initState();
animationController =
AnimationController(vsync: this, duration: Duration(seconds: 10));
animation = Tween(begin: 0.0, end: 100.0).animate(animationController);
animationController.forward(); //啓動動畫
}
@override
Widget build(BuildContext context) {
return TestTransition(
child: Center(
child: Container(
color: Colors.red,
)),
animation: animation,
);
}
}
複製代碼