Flutter內建了很多的Tween,下面一一看下:
ColorTween
可以設定顏色漸變,begin顏色,end顏色,中間過渡。
- 設定顏色過渡,初始顏色綠色,目標顏色棕色,Tween colorTween = new ColorTween(begin: Colors.green,end:Colors.orange);
- 方式一:通過colorTween.evaluate(_controller)來獲取漸變的顏色
- 方式二:通過animate
- Animation _animation
- new ColorTween(begin: Colors.green, end: Colors.orange);
- _animation = colorTween.animate(_controller);
- color: _animation.value
程式碼如下:
import 'package:flutter/material.dart';
class Test10ColorTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test10ColorTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween colorTween = new ColorTween(begin: Colors.green, end: Colors.orange);
Animation<Color> _animationColor;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 5000));
_animationColor = colorTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ColorTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: colorTween.evaluate(_controller),
),
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: _animationColor.value,
),
Text("ColorTween",
style: TextStyle(
fontSize: 14,
)),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
IntTween
直接new Tween()時,begin 和 end是double的,IntTween的begin和end是int型的。
Tween sizeTween = new IntTween(begin: 0,end: 200);
print("${sizeTween.evaluate(_controller)}");
複製程式碼
- 通過evaluate,列印的值全是int的。
- 通過animate.value獲取到的值都是int的。
程式碼如下:
import 'package:flutter/material.dart';
class Test09IntTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test09IntTween> with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween intTween = new IntTween(begin: 0, end: 200);
Animation<int> _animationInt;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 6000));
_animationInt = intTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("IntTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: _animationInt.value.toDouble(),
height: _animationInt.value.toDouble(),
margin: EdgeInsets.all(10),
color: Colors.black12,
),
Text("IntTween,_animationInt.value=${_animationInt.value}",
style: TextStyle(
fontSize: 14,
)),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
SizeTween
基於Size的過渡變化,其實是size內兩個值的變化。
Tween sizeTween = new SizeTween(begin: Size(0.0,0.0),end: Size(100.0,100.0));
Animation<Size> animation = sizeTween.animate(_controller);
Size size = animation.value;
複製程式碼
- 注意Animation animation = sizeTween.animate(_controller); 泛型是Size
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test11SizeTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test11SizeTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween sizeTween =
new SizeTween(begin: Size(0.0, 0.0), end: Size(100.0, 200.0));
Animation<Size> _animationSize;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 5000));
_animationSize = sizeTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SizeTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: _animationSize.value.width,
height: _animationSize.value.height,
margin: EdgeInsets.all(10),
color: Colors.black12,
),
Container(
width: 300,
child: Text("SizeTween.size.width=${_animationSize.value.width}",
style: TextStyle(
fontSize: 14,
)),
),
Container(
width: 300,
child:
Text("SizeTween.size.height=${_animationSize.value.height}",
style: TextStyle(
fontSize: 14,
)),
)
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
RectTween
基於Rect矩形的過渡變化
Tween rectTween = new RectTween(begin: Rect.fromLTWH(0, 0, 0, 0),end: Rect.fromLTWH(100, 100, 100, 100));
Animation<Rect> animation = rectTween.animate(_controller);
Rect rect = animation.value;
複製程式碼
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test12RectTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test12RectTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween rectTween = new RectTween(
begin: Rect.fromLTWH(0, 0, 0, 0), end: Rect.fromLTWH(100, 100, 100, 100));
Animation<Rect> _animationRect;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 5000));
_animationRect = rectTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("RectTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: Colors.black12,
child: CustomPaint(
painter: _MyRectPainter(_animationRect),
),
),
Text("RectTween",
style: TextStyle(
fontSize: 14,
)),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyRectPainter extends CustomPainter {
Animation<Rect> animation;
_MyRectPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.red
..strokeWidth = 1
..style = PaintingStyle.stroke;
canvas.drawRect(animation.value, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
複製程式碼
StepTween
每次返回插值的floor,從double變為了int。
Tween stepTween = new StepTween(begin: 0,end: 100);
Animation<int> animation = stepTween.animate(_controller);
int value = animation.value;
複製程式碼
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test13StepTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test13StepTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween stepTween = new StepTween(begin: 0, end: 100);
Animation<int> _animationStep;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 6000));
_animationStep = stepTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StepTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: Colors.black12,
child: CustomPaint(
painter: _MyStepPainter(_animationStep),
),
),
Text("StepTween.value=${_animationStep.value}",
style: TextStyle(
fontSize: 14,
)),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyStepPainter extends CustomPainter {
Animation<int> animation;
_MyStepPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.red
..strokeWidth = 1
..style = PaintingStyle.stroke;
canvas.drawRect(
Rect.fromLTWH(
0, 0, animation.value.toDouble(), animation.value.toDouble()),
paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
複製程式碼
ConstantTween
每次返回插常量值,建立時傳入什麼型別的值,就獲取什麼型別的值
Tween constantTween = new ConstantTween(100.0);
Animation<int> animation = constantTween.animate(_controller);
int value = animation.value;
複製程式碼
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test14ConstantTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test14ConstantTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween constantTween = new ConstantTween<String>("ConstantTween");
Animation<String> _animationConstant;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this, duration: const Duration(milliseconds: 5000));
_animationConstant = constantTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ConstantTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: Colors.black12,
child: Center(
child: Text(_animationConstant.value,
style: TextStyle(fontSize: 14, color: Colors.red)),
),
),
Text("ConstantTween",
style: TextStyle(
fontSize: 14,
)),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
CurveTween
注意CurveTween extends Animatable,不是Tween的子類。用給定的curve將_controller.value進行了轉換。
CurveTween curveTween = new CurveTween(curve:Curves.easeInToLinear);
Animation<double> animation = curveTween.animate(_controller);
double value = animation.value;
複製程式碼
- animation.value值在[0,1]之間
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test15CurveTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test15CurveTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
CurveTween curveTween = new CurveTween(curve: Curves.bounceInOut);
Animation<double> _animationCurve;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animationCurve = curveTween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("CurveTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: Colors.black12,
child: CustomPaint(
painter: _MyCurvePainter(_animationCurve),
),
),
Container(
width: 300,
child: Text("CurveTween.value=${_animationCurve.value}",
style: TextStyle(
fontSize: 14,
)),
)
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyCurvePainter extends CustomPainter {
Animation<double> animation;
_MyCurvePainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
translateToCenter(canvas, size);
Paint paint = Paint()
..color = Colors.red
..style = PaintingStyle.fill;
canvas.drawCircle(
Offset(animation.value * 100, animation.value * 100), 10, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
複製程式碼
AlignmentTween
基於Alignment屬性的過渡,比如Container的child從topleft移動到bottomRight.
看下效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test16AlignmentTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test16AlignmentTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween =
new AlignmentTween(begin: Alignment.topLeft, end: Alignment.bottomRight);
Animation<Alignment> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AlignmentTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
alignment: _animation.value,
margin: EdgeInsets.all(10),
color: Colors.black12,
child: Container(
width: 100,
height: 100,
color: Colors.orange,
),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
AlignmentGeometryTween
與AlignmentTween類似效果。 效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test17AlignmentGeometryTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test17AlignmentGeometryTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new AlignmentGeometryTween(
begin: AlignmentDirectional.topCenter,
end: AlignmentDirectional.centerEnd);
Animation<AlignmentGeometry> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AlignmentGeometryTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
color: Colors.black12,
alignment: _animation.value,
child: Container(
width: 100,
height: 100,
color: Colors.orange,
),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
BorderRadiusTween
基於BorderRadius屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test18BorderRadiusTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test18BorderRadiusTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new BorderRadiusTween(
begin: BorderRadius.circular(0), end: BorderRadius.circular(200));
Animation<BorderRadius> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BorderRadiusTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(borderRadius: _animation.value,color: Colors.orangeAccent),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
BorderTween
基於Border屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test19BorderTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test19BorderTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new BorderTween(
begin: Border(top: BorderSide(width: 0, color: Colors.red)),
end: Border(
top: BorderSide(width: 50, color: Colors.green),
bottom: BorderSide(width: 50, color: Colors.blueAccent)));
Animation<Border> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BorderTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: _animation.value, color: Colors.orangeAccent),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
ShapeBorderTween
基於ShapeBorder屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test20ShapeBorderTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test20ShapeBorderTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new ShapeBorderTween(
begin: RoundedRectangleBorder(
side: BorderSide(width: 0, color: Colors.red),
borderRadius: BorderRadius.circular(0)),
end: RoundedRectangleBorder(
side: BorderSide(width: 50, color: Colors.green),
borderRadius: BorderRadius.circular(200)));
Animation<ShapeBorder> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ShapeBorderTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
decoration: ShapeDecoration(shape: _animation.value,color: Colors.orangeAccent),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
DecorationTween
基於Decoration屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test21DecorationTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test21DecorationTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new DecorationTween(
begin: BoxDecoration(
color: Colors.red,
// borderRadius: BorderRadius.circular(0),
border: Border(top: BorderSide(color: Colors.red, width: 0)),
// shape: BoxShape.rectangle,
gradient: LinearGradient(
colors: [Colors.red, Colors.green, Colors.blueAccent])),
end: BoxDecoration(
color: Colors.orangeAccent,
// borderRadius: BorderRadius.circular(200),
border: Border(top: BorderSide(color: Colors.black, width: 50)),
// shape: BoxShape.circle,
gradient: LinearGradient(colors: [
Colors.black12,
Colors.blueAccent,
Colors.yellowAccent
])));
Animation<Decoration> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DecorationTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
decoration: _animation.value,
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
BoxConstraintsTween
基於BoxConstraints屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test22BoxConstraintsTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test22BoxConstraintsTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new BoxConstraintsTween(
begin: BoxConstraints(maxWidth: 0, minHeight: 0),
end: BoxConstraints(maxWidth: 200, minHeight: 200));
Animation<BoxConstraints> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BoxConstraintsTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
constraints: _animation.value,
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
EdgeInsetsTween
基於padding 或 margin等需要EdgeInsets控制的屬性的過渡。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test23EdgeInsetsTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test23EdgeInsetsTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new EdgeInsetsTween(
begin: EdgeInsets.only(left: 0, top: 0),
end: EdgeInsets.only(left: 100, top: 50));
Animation<EdgeInsets> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("EdgeInsetsTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
padding: _animation.value,
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
child: Text("pushing by padding"),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
EdgeInsetsGeometryTween
基於padding 或 margin等需要EdgeInsetsGeometry控制的屬性的過渡。EdgeInsetsGeometry是EdgeInsets的父類。效果幾乎一樣。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test24EdgeInsetsGeometryTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test24EdgeInsetsGeometryTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new EdgeInsetsGeometryTween(
begin: EdgeInsets.only(left: 0, top: 0),
end: EdgeInsets.only(left: 100, top: 50));
Animation<EdgeInsetsGeometry> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("EdgeInsetsGeometryTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
padding: _animation.value,
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
child: Text("pushing by padding"),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
TextStyleTween
基於Text的style屬性的過渡,TextStyle的所有屬性都可以漸變。
效果如下:
程式碼如下:
import 'package:flutter/material.dart';
class Test25TextStyleTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test25TextStyleTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new TextStyleTween(
begin: TextStyle(color: Colors.red,fontSize: 10),
end: TextStyle(color: Colors.blue,fontSize: 40));
Animation<TextStyle> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TextStyleTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
alignment: Alignment.center,
child: Text("TextStyle changing",style: _animation.value,),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
Matrix4Tween
基於四階矩陣的漸變,以canvas的transform為例。
效果:
程式碼如下:
import 'package:flutter/material.dart';
class Test26Matrix4Tween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test26Matrix4Tween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new Matrix4Tween(
begin: Matrix4(
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1,
),
end: Matrix4(
1,0,0,0,
0,1,0,0,
0,0,1,0,
100,0,0,1,// 延x平移100
));
Animation<Matrix4> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Matrix4Tween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
alignment: Alignment.center,
child: CustomPaint(
size: Size(200,200),
painter: _MyRectPainter(_animation),
),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyRectPainter extends CustomPainter {
Animation<Matrix4> animation;
_MyRectPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
translateToCenter(canvas, size);
Paint paint = Paint()
..color = Colors.red
..strokeWidth = 1
..style = PaintingStyle.stroke;
canvas.drawCircle(Offset.zero, 100, paint);
canvas.transform(animation.value.storage);
canvas.drawCircle(Offset.zero, 100, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
複製程式碼
Test27ThemeDataTween
可以定義主題漸變的Tween. 效果:
程式碼:
import 'package:flutter/material.dart';
class Test27ThemeDataTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test27ThemeDataTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new ThemeDataTween(
begin: ThemeData(primaryColor: Colors.blue),
end: ThemeData(primaryColor: Colors.green));
Animation<ThemeData> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Theme(
data: _animation.value,
child: Scaffold(
appBar: AppBar(
title: Text("ThemeDataTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
color: _animation.value.primaryColor,
),
],
),
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
複製程式碼
Test28RelativeRectTween
可以定義主題漸變的Tween. 效果:
程式碼:
import 'package:flutter/material.dart';
class Test28RelativeRectTween extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<Test28RelativeRectTween>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween = new RelativeRectTween(
begin: RelativeRect.fromLTRB(0, 0, 0, 0),
end: RelativeRect.fromLTRB(100, 100, 100, 100));
Animation<RelativeRect> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);
_animation = _tween.animate(_controller);
_controller.addListener(() {
setState(() {});
});
// 動畫開始執行
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("RelativeRectTween"),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 400,
height: 400,
margin: EdgeInsets.all(10),
color: Colors.orangeAccent,
child: CustomPaint(
painter: _MyRectPainter(_animation),
),
),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class _MyRectPainter extends CustomPainter {
Animation<RelativeRect> animation;
_MyRectPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.red
..strokeWidth = 1
..style = PaintingStyle.stroke;
Rect rect = Rect.fromLTWH(0, 0, size.width,size.height);
canvas.drawRect(animation.value.toRect(rect), paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
void translateToCenter(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
}
}
複製程式碼
Tween總結
flutter提供了有二十個左右的Tween,從基本型別到物件都有,但是有個明顯的特點:
- 可量化,就算是物件,如Decoration,其實也是對其屬性的變化,都是可量化的。
- 同一型別的變化,begin描述初始狀態,end描述結束狀態
親自動手試了這麼多Tween的效果,其實可以發現,本質都是對AnimationController插值[0,1]變化的封裝,我們自己也可以實現這些效果,只是flutter封裝後我們更便於使用。