前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【 开源计划 - Flutter组件】 旋转切换 toggle_rotate

【 开源计划 - Flutter组件】 旋转切换 toggle_rotate

作者头像
张风捷特烈
发布2020-04-30 13:44:36
8180
发布2020-04-30 13:44:36
举报

pub地址 】 【github地址

代码语言:javascript
复制
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.最简使用:
代码语言:javascript
复制
ToggleRotate(
  child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent),
  onTap: () {}, //点击事件
),

3.指定时长和曲线和方向
代码语言:javascript
复制
ToggleRotate(
  curve: Curves.decelerate,
  durationMs: 400,//动画时长
  clockwise: false, //是否是顺时针
  child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent),
  onTap: () {},
),

4.可使一切组件进行旋转切换
代码语言:javascript
复制
ToggleRotate(
  curve: Curves.decelerate,
  durationMs: 400,
  child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")),
  onTap: () {},
)

5.可使旋转的角度
代码语言:javascript
复制
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

代码语言:javascript
复制
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置反

代码语言:javascript
复制
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决定是否是顺时针旋转,这样该组件就完成了。

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年03月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、描述
    • 1.所有属性:
      • 2.最简使用:
        • 3.指定时长和曲线和方向
          • 4.可使一切组件进行旋转切换
            • 5.可使旋转的角度
            • 二、实现原理
              • 1.自定义组件
                • 2.动画器的创建和销毁
                  • 3.通过Transform实现变换
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档