【 开源计划 - Flutter组件】 旋转切换 toggle_rotate
2020/3/8 8:01:41
本文主要是介绍【 开源计划 - Flutter组件】 旋转切换 toggle_rotate,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、描述
目标: 让一个组件点击时执行旋转,再点击旋转回去。
最简使用
时长、曲线、方向
可含一切组件
旋转角度
1.所有属性:
2.最简使用:
ToggleRotate( child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent), onTap: () {}, //点击事件 ),
3.指定时长和曲线和方向
ToggleRotate( curve: Curves.decelerate, durationMs: 400,//动画时长 clockwise: false, //是否是顺时针 child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent), onTap: () {}, ),
4.可使一切组件进行旋转切换
ToggleRotate( curve: Curves.decelerate, durationMs: 400, child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")), onTap: () {}, )
5.可使旋转的角度
ToggleRotate( rad: pi / 4, curve: Curves.linear, child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")), onTap: () {}, )
二、实现原理
点击时进行一些动画效果比较好看,顺便抽离成一个组件分享一下
这个小组件是一个动画的经典案例,所以分析一下具体实现还是很有意义的
1.自定义组件
开始分析一下是否有状态。很明显,我们需要在点击时让组件旋转
组件有是否旋转是一个状态量,旋转过程中的角度也是状态量
可以说想要实现动画,基本上是基于StatefulWidget的,先写出一个基本的组件
由于需要动画,要with SingleTickerProviderStateMixin
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(); } }
2.动画器的创建和销毁
状态量有旋转的弧
_rad
、是否已旋转_rotated
。
动画器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(); }
3.通过Transform实现变换
在点击时先重设控制器,然后再执行。否则第二次是不会动的
在这里只用onTap回调点击事件,暴露给外界处理。
clockwise决定是否是顺时针旋转,这样该组件就完成了。
@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组件】 旋转切换 toggle_rotate的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-19永别了,微服务架构!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?