您的位置 首页 > 腾讯云社区

【 开源计划 - Flutter组件】 旋转切换 toggle_rotate---张风捷特烈

【pub地址 】 【github地址】

dependencies: toggle_rotate: $lastVersion 一、描述

目标: 让一个组件点击时执行旋转,再点击旋转回去。

最简使用

时长、曲线、方向

可含一切组件

旋转角度

1.所有属性:

名称

类型

功能

备注

默认

rad

double

旋转角度

弧度制

pi / 2

durationMs

int

动画时长

毫秒

200

curve

Curve

动画曲线

-

Curves.fastOutSlowIn

clockwise

bool

是否顺时针旋转

-

true

onTap

Function

点击事件

@required

null

child

Widget

子组件

@required

null

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行左右的代码,但包含很多知识点。 如果你想要一个组件在点击时不那么古板,欢迎使用

---来自腾讯云社区的---张风捷特烈

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: