【pub 】 【github 】
dependencies:
toggle_rotate: $lastVersion
Copy the code
A, description,
Goal: Make a component rotate when clicked, and rotate back when clicked.
The simplest use | Duration, curve, direction | Can contain all components | Rotation Angle |
---|---|---|---|
1. All attributes:
The name of the | type | function | note | The default |
---|---|---|---|---|
rad | double | Rotation Angle | Radian system | pi / 2 |
durationMs | int | Animation duration | ms | 200 |
curve | Curve | The animation curve | – | Curves.fastOutSlowIn |
clockwise | bool | Whether to rotate clockwise | – | true |
onTap | Function | Click on the event | @required | null |
child | Widget | Child components | @required | null |
2. Simplest use:
ToggleRotate(child: Icon(Icons. Arrow_upward,size: 60,color: Colors. OrangeAccent), onTap: () {}, // Click the event),Copy the code
3. Specify the duration, curve, and direction
ToggleRotate(Curve: Curves. Activity, durationMs: 400,// Animation length approval: false, // Clockwise child: Icon(Icons.arrow_upward,size: 60,color: Colors.orangeAccent), onTap: () {}, ),Copy the code
4. Rotate and switch all components
ToggleRotate(
curve: Curves.decelerate,
durationMs: 400,
child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")),
onTap: () {},
)
Copy the code
5. Angle that can be rotated
ToggleRotate(
rad: pi / 4,
curve: Curves.linear,
child: Image(width:60,height: 60,image: AssetImage("assets/images/icon_28.jpg")),
onTap: () {},
)
Copy the code
Two, the implementation principle
Click on some animation effect is better, by the way, pull out into a component to share
This widget is a classic example of animation, so it’s interesting to look at the implementation
1. Customize components
Let’s start analyzing if we have any states. Obviously, we need to rotate the component when we click
Component has a rotation is a state variable, in the process of rotating Angle is also a state Can be said to want to achieve animation, basically is based on the StatefulWidget, first to write a basic components Due to the movie, to be 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(); }}Copy the code
2. Animator creation and destruction
The value of states includes arc rad of rotation, whether it was rotated or not.
The AnimationController is responsible for making the number change evenly between 0.0 and 1.0. To make the number change rate to the core of the curve through the CurvedAnimation is to determine the size of the radian during each update of the state. The addListener allows you to listen every time the animator is refreshed and the state of the animation can be monitored by the addStatusListener if it’s done _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(); }Copy the code
3. Use Transform to Transform
Reset the controller when clicked, and then execute. Otherwise it won’t move the second time
In this case, just the onTap callback click event is exposed for external processing. Deciding if the rotation is clockwise is then complete with the component.
@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,
),
);
}
Copy the code
Although it’s a small piece of code, it’s only about 60 lines of code, but it contains a lot of knowledge.
If you want a component that is less stuffy when clicked, use it
The end of the
In addition, I have a Flutter wechat communication group. You are welcome to join and discuss Flutter issues together. I look forward to exchanging ideas with you.
@ZhangFengjietele 2019.02.23 not allowed to transfer
My official number: King of programming contact me – email :[email protected] – wechat :zdl1994328 ~ END ~