Transition

Transition内部使用了属性动画实现,是一种属性动画的封装。Transition主要负责两个方面,一是保存开始和结束场景的状态。二是两种状态之间创建动画。

Scene

Scene 场景过渡动画就是实现View从一个状态变化到另一个状态,Scene就代表一个场景,内部保存一个完整的视图结构

Scene(ViewGroup sceneRoot)
Scene(ViewGroup sceneRoot, View layout)

AnimationController

1
AnimationController(vsync:this, duration: Duration(milliseconds: 5000));
  • vsync 防止屏幕外动画消耗不必要的资源 单个AnimationController使用SingleTickerProviderStateMixin,多个AnimationController使用TickerProviderStateMixin
  • duration 动画执行的时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class _AnimationBaseDemoState extends State<AnimationBaseDemo> with SingleTickerProviderStateMixin {
double _size = 100;
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this,duration: Duration(milliseconds: 500),lowerBound: 100,upperBound: 200)
..addListener(() {
setState(() {
_size = _controller.value;
});
})
}

@override
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
onTap: () {
_controller.forward();
},
child: Container(
height: _size,
width: _size,
color: Colors.blue,
alignment: Alignment.center,
child: Text('点我变大',style: TextStyle(color: Colors.white,fontSize: 18),),
),
),
);
}

@override
void dispose() {
super.dispose();
_controller.dispose();
}
}
  • dismissed 动画停止在开始处
  • forward 动画从开始处运行到结束处
  • reverse 动画充结束处运行到开始处
  • completed 动画结束在借书处
  • repeat 重复执行动画
  • reset 重置动画

Tween

动画映射

1
2
3
4
5
6
7
8
9
AnimationController _controller;
Animation<Color> _animation;

@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: 500));
_animation = ColorTween(begin: Colors.blue, end: Colors.red).animate(_controller);
}

Curve

动画曲线

1
2
3
4
5
6
7
8
9
10
11
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 1000))
..addListener(() {
setState(() {});
});

_animation = Tween(begin: 100.0, end: 200.0)
.chain(CurveTween(curve: Curves.bounceIn))
.animate(_controller);
}

自定义曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class _StairsCurve extends Curve {
final int num;
double _perStairY;
double _perStairX;

_StairsCurve(this.num) {
_perStairY = 1.0 / (num - 1);
_perStairX = 1.0 / num;
}

@override
double transformInternal(double t) {
return _perStairY * (t / _perStairX).floor();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int countValue = 10;
Timer _timer;

void startTimer() {
final Duration duration = Duration(seconds: 1);
cancelTimer();

_timer = Timer.periodic(duration, (timer) {
countValue = countValue - 1;
if (this.mounted) {
setState((){
//..
});
}
print(countValue);
if (countValue <= 0) {
cancelTimer();
}
});
}

常见问题

  1. Widget销毁时取消Timer
1
2
3
4
5
@override
void dispose() {
cancelTimer();
super.dispose();
}
  1. 生命周期变动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch(state) {
case AppLifecycleState.resumed: {
break;
}
case AppLifecycleState.paused: {
cancelTimer();
break;
}
case AppLifecycleState.inactive: {
cancelTimer();
break;
}
case AppLifecycleState.detached: {
cancelTimer();
break;
}
}
super.didChangeAppLifecycleState(state);
}