This article has authorized the exclusive publication and reproducing of the Wechat Public Number Y YYGeeker. Please indicate the source.
Control introduction
- Positioned Transition represents an animation of a rectangular position, which can be controlled by the controller to change the rectangular value of the animation, thereby controlling the rectangular position of the animation.
Constructor
PositionedTransition({ Key key, this.rect, //Change of rectangular position value in animation Widget child, //Animation sub-elements })
Usage method
1. Packaging animation
We can wrap common attributes as a control
- child: Represents elements passed in from outside, wrapped by Positioned Transition
- rect: Represents the change in the value of the animation attribute passed in from outside, and fills it in the rectangular position of the child by obtaining its value.
Note here that the parent control of PositionedTransition must be Stack
class AnimatorTransition extends StatelessWidget { final Widget child; final Animation<RelativeRect> animation; AnimatorTransition({this.child, this.animation}); @override Widget build(BuildContext context) { //The animation of absolute positioning needs Stack package return Stack( children: <Widget>[ PositionedTransition( rect: animation, child: this.child, ), ], ); } }
2. Control animation
- Animation Controller is needed to control the change of animation attribute values.
- Setting up its interpolator through Curved Animation
- Set the range of its value by Relative RectTween
class WeWidgetState extends State<WeWidget> with SingleTickerProviderStateMixin { Animation<RelativeRect> _animation; AnimationController _controller; Animation _curve; @override void initState() { super.initState(); //Animation Controller _controller = AnimationController( duration: const Duration(milliseconds: 3000), vsync: this, ); //Animation Interpolator _curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn); //Range of animation change _animation = RelativeRectTween( begin: RelativeRect.fromLTRB(200.0, 200.0, 200.0, 200.0), end: RelativeRect.fromLTRB(20.0, 20.0, 20.0, 20.0)) .animate(_curve); //Start animation _controller.forward(); } }
3. Monitoring animation
- Monitor changes in animation status by addStatusListener and changes in animation value by addListener
class WeWidgetState extends State<WeWidget> with SingleTickerProviderStateMixin { Animation<RelativeRect> _animation; AnimationController _controller; Animation _curve; double _animationValue; AnimationStatus _state; @override void initState() { super.initState(); //Animation Controller _controller = AnimationController( duration: const Duration(milliseconds: 3000), vsync: this, ); //Animation Interpolator _curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn); //Range of animation change _animation = RelativeRectTween( begin: RelativeRect.fromLTRB(200.0, 200.0, 200.0, 200.0), end: RelativeRect.fromLTRB(20.0, 20.0, 20.0, 20.0)) .animate(_curve) ..addListener(() { setState(() { //Record changes in values _animationValue = _animation.value; }); }) ..addStatusListener((AnimationStatus state) { //If the animation is finished, reverse the drawing. if (state == AnimationStatus.completed) { _controller.reverse(); } else if (state == AnimationStatus.dismissed) { //If the animation has disappeared, start animation _controller.forward(); } setState(() { _state = state; }); }); //Start animation _controller.forward(); } }
Design sketch
source code
import 'package:flutter/material.dart'; class Day13 extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primaryColor: Colors.white, ), home: WeWidget(), ); } } class WeWidget extends StatefulWidget { @override State<StatefulWidget> createState() { return WeWidgetState(); } } class WeWidgetState extends State<WeWidget> with SingleTickerProviderStateMixin { Animation<RelativeRect> _animation; AnimationController _controller; Animation _curve; RelativeRect _animationValue; AnimationStatus _state; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 3000), vsync: this, ); _curve = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn); _animation = RelativeRectTween( begin: RelativeRect.fromLTRB(200.0, 200.0, 200.0, 200.0), end: RelativeRect.fromLTRB(20.0, 20.0, 20.0, 20.0)) .animate(_curve) ..addListener(() { setState(() { _animationValue = _animation.value; }); }) ..addStatusListener((AnimationStatus state) { if (state == AnimationStatus.completed) { _controller.reverse(); } else if (state == AnimationStatus.dismissed) { _controller.forward(); } setState(() { _state = state; }); }); _controller.forward(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("day13"), ), body: _buildColumn(), ); } Widget _buildColumn() { return Stack( children: <Widget>[ AnimatorTransition( child: FlutterLogo( style: FlutterLogoStyle.horizontal, size: 200, ), animation: _animation, ), Padding( padding: EdgeInsets.fromLTRB(0, 15, 0, 0), child: Text("Animation value:" + _animationValue.toString()), ), Padding( padding: EdgeInsets.fromLTRB(0, 30, 0, 0), child: Text("Animation status:" + _state.toString()), ), ], ); } @override void dispose() { _controller.dispose(); super.dispose(); } } class AnimatorTransition extends StatelessWidget { final Widget child; final Animation<RelativeRect> animation; AnimatorTransition({this.child, this.animation}); @override Widget build(BuildContext context) { //The animation of absolute positioning needs Stack package return Stack( children: <Widget>[ PositionedTransition( rect: animation, child: this.child, ), ], ); } }