本篇文章已授權微信公衆號 YYGeeker
獨家發佈轉載請標明出處
控件介紹
ScaleTransition
表示一個縮放動畫,可以通過控制器去控制動畫縮放值的改變,從而控制動畫的縮放
構造函數
ScaleTransition({
Key key,
this.scale, //動畫縮放值的變化
this.alignment, //旋轉的錨定座標
Widget child, //動畫子元素
})
使用方法
1、封裝動畫
我們可以將常用屬性包裝成一個控件
- child:表示由外傳遞進來的元素,由
ScaleTransition
包裹 - scale:表示由外傳遞進來的動畫屬性值的變化,通過獲取其值,填充到
child
的縮放值上 - alignment:表示縮放的錨定座標
class AnimatorTransition extends StatelessWidget {
final Widget child;
final Animation<num> animation;
AnimatorTransition({this.child, this.animation});
@override
Widget build(BuildContext context) {
return Center(
child: ScaleTransition(
//縮放的錨定座標
alignment: Alignment.topLeft,
scale: animation,
child: this.child,
),
);
}
}
2、控制動畫
- 動畫屬性值的變化需要
AnimationController
來控制 - 通過
CurvedAnimation
設置其插值器 - 通過
Tween
設置其值的變化範圍
class WeWidgetState extends State<WeWidget>
with SingleTickerProviderStateMixin {
Animation<num> _animation;
AnimationController _controller;
Animation _curve;
@override
void initState() {
super.initState();
//動畫控制器
_controller = AnimationController(
duration: const Duration(milliseconds: 3000),
vsync: this,
);
//動畫插值器
_curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
//動畫變化範圍
_animation = Tween(begin: 0.0, end: 1.0).animate(_curve);
//啓動動畫
_controller.forward();
}
}
3、監聽動畫
- 通過
addStatusListener
監聽動畫狀態的變化和通過addListener
監聽動畫值的變化
class WeWidgetState extends State<WeWidget>
with SingleTickerProviderStateMixin {
//嘗試擴展或實現num時,除int或double之外的任何類型都是編譯時錯誤
Animation<num> _animation;
AnimationController _controller;
Animation _curve;
double _animationValue;
AnimationStatus _state;
@override
void initState() {
super.initState();
//動畫控制器
_controller = AnimationController(
duration: const Duration(milliseconds: 3000),
vsync: this,
);
//動畫插值器
_curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
//動畫變化範圍
_animation = Tween(begin: 0.0, end: 1.0).animate(_curve)
..addListener(() {
setState(() {
//記錄變化的值
_animationValue = _animation.value;
});
})
..addStatusListener((AnimationStatus state) {
//如果動畫已完成,就反轉動畫
if (state == AnimationStatus.completed) {
_controller.reverse();
} else if (state == AnimationStatus.dismissed) {
//如果動畫已經消失,則開始動畫
_controller.forward();
}
setState(() {
_state = state;
});
});
//啓動動畫
_controller.forward();
}
}
效果圖
源代碼
import 'package:flutter/material.dart';
class Day15 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.white,
),
home: WeWidget(),
);
}
}
class WeWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return WeWidgetState();
}
}
class WeWidgetState extends State<WeWidget>
with SingleTickerProviderStateMixin {
//嘗試擴展或實現num時,除int或double之外的任何類型都是編譯時錯誤
Animation<num> _animation;
AnimationController _controller;
Animation _curve;
double _animationValue;
AnimationStatus _state;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 3000),
vsync: this,
);
_curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
_animation = Tween(begin: 0.0, end: 1.0).animate(_curve)
..addListener(() {
setState(() {
_animationValue = _animation.value;
});
})
..addStatusListener((AnimationStatus state) {
if (state == AnimationStatus.completed) {
_controller.reverse();
} else if (state == AnimationStatus.dismissed) {
_controller.forward();
}
setState(() {
_state = state;
});
});
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("day15"),
),
body: _buildColumn(),
);
}
Widget _buildColumn() {
return Column(
children: <Widget>[
AnimatorTransition(
child: FlutterLogo(
style: FlutterLogoStyle.horizontal,
size: 200,
),
animation: _animation,
),
Text("動畫值:" + _animationValue.toString()),
Text("動畫狀態:" + _state.toString()),
],
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class AnimatorTransition extends StatelessWidget {
final Widget child;
final Animation<num> animation;
AnimatorTransition({this.child, this.animation});
@override
Widget build(BuildContext context) {
return Center(
child: ScaleTransition(
//縮放的錨定座標
alignment: Alignment.topLeft,
scale: animation,
child: this.child,
),
);
}
}