dependencies:
toggle_rotate: $lastVersion
複製代碼
目標: 讓一個組件點擊時執行旋轉,再點擊旋轉回去。github
最簡使用 | 時長、曲線、方向 | 可含一切組件 | 旋轉角度 |
---|---|---|---|
名稱 | 類型 | 功能 | 備註 | 默認 |
---|---|---|---|---|
rad | double | 旋轉角度 | 弧度制 | pi / 2 |
durationMs | int | 動畫時長 | 毫秒 | 200 |
curve | Curve | 動畫曲線 | - | Curves.fastOutSlowIn |
clockwise | bool | 是否順時針旋轉 | - | true |
onTap | Function | 點擊事件 | @required | null |
child | Widget | 子組件 | @required | null |
ToggleRotate(
child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent),
onTap: () {}, //點擊事件
),
複製代碼
ToggleRotate(
curve: Curves.decelerate,
durationMs: 400,//動畫時長
clockwise: false, //是不是順時針
child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent),
onTap: () {},
),
複製代碼
ToggleRotate(
curve: Curves.decelerate,
durationMs: 400,
child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")),
onTap: () {},
)
複製代碼
ToggleRotate(
rad: pi / 4,
curve: Curves.linear,
child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")),
onTap: () {},
)
複製代碼
點擊時進行一些動畫效果比較好看,順便抽離成一個組件分享一下編程
這個小組件是一個動畫的經典案例,因此分析一下具體實現仍是頗有意義的微信
開始分析一下是否有狀態。很明顯,咱們須要在點擊時讓組件旋轉markdown
組件有是否旋轉是一個狀態量,旋轉過程當中的角度也是狀態量
能夠說想要實現動畫,基本上是基於StatefulWidget的,先寫出一個基本的組件
因爲須要動畫,要with SingleTickerProviderStateMixin
ide
library toggle_rotate;
import 'dart:math';
import 'package:flutter/material.dart';
class ToggleRotate extends StatefulWidget {
final Widget child;
final Function onTap;
final double rad;
final int durationMs;
final bool clockwise;
final Curve curve;
ToggleRotate(
{this.child,
@required this.onTap,
this.rad = pi / 2,
this.clockwise = true,
this.durationMs = 200,
this.curve = Curves.fastOutSlowIn});
@override
_ToggleRotateState createState() => _ToggleRotateState();
}
class _ToggleRotateState extends State<ToggleRotate> with SingleTickerProviderStateMixin {
@override
void initState() {
super.initState();
}
@override
void dispose()
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
複製代碼
狀態量有旋轉的弧
_rad
、是否已旋轉_rotated
。oop
動畫器AnimationController負責讓數字在0.0~1.0之間均勻變化
經過CurvedAnimation來讓數字變化率爲曲線
核心就是肯定每次更新狀態時弧度的大小。 經過addListener能夠在動畫器每次刷新時進行監聽
經過addStatusListener對動畫的狀態進行監聽,若是完成_rotated置反動畫
class _ToggleRotateState extends State<ToggleRotate>
with SingleTickerProviderStateMixin {
double _rad = 0;
bool _rotated = false;
AnimationController _controller;
Animation _rotate;
@override
void initState() {
_controller = AnimationController(
duration: Duration(milliseconds: widget.durationMs), vsync: this)
..addListener(() => setState(() =>
_rad = (_rotated ? (1 - _rotate.value) : _rotate.value) * widget.rad))
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_rotated = !_rotated;
}
});
_rotate = CurvedAnimation(parent: _controller, curve: widget.curve);
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
複製代碼
在點擊時先重設控制器,而後再執行。不然第二次是不會動的ui
在這裏只用onTap回調點擊事件,暴露給外界處理。
clockwise決定是不是順時針旋轉,這樣該組件就完成了。this
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_controller.reset();
_controller.forward();
widget.onTap();
},
child: Transform(
transform: Matrix4.rotationZ(widget.clockwise ? _rad : -_rad),
alignment: Alignment.center,
child: widget.child,
),
);
}
複製代碼
麻雀雖小五臟俱全,這個小組件雖然就60行左右的代碼,但包含不少知識點。
若是你想要一個組件在點擊時不那麼古板,歡迎使用
另外本人有一個Flutter微信交流羣,歡迎小夥伴加入,共同探討Flutter的問題,期待與你的交流與切磋。
@張風捷特烈 2019.02.23 未允禁轉
個人公衆號:編程之王
聯繫我--郵箱:1981462002@qq.com --微信:zdl1994328
~ END ~