当前位置:网站首页>[shutter] hero animation (hero realizes radial animation | hero component createrecttween setting)
[shutter] hero animation (hero realizes radial animation | hero component createrecttween setting)
2022-07-03 01:52:00 【Programmer community】
List of articles
- ◯、Hero Constructors
- One 、 Round square components
- Two 、 Create a page 1 The components of ( Hero Components 1 )
- 3、 ... and 、 Create a page 2 The components of ( Hero Components 2 )
- Four 、 Complete code example
- 5、 ... and 、 Related resources
◯、Hero Constructors
Hero Constructors :
/// Create a Hero Components ; /// /// tag , child The parameter cannot be null ; /// child The value of the parameter cannot be Hero Components and Hero Component subclass ; const Hero({
Key? key, required this.tag, this.createRectTween, this.flightShuttleBuilder, this.placeholderBuilder, this.transitionOnUserGestures = false, required this.child, }) : assert(tag != null), assert(transitionOnUserGestures != null), assert(child != null), super(key: key);
required this.tag : Can't be empty , be used for Associated with two interfaces Hero Components , Two Hero Components are related , Then set the same tag character string ;
this.createRectTween : Can be null , be used for Definition Hero Boundary of component , And the definition Hero When components switch interfaces , from The starting position of the source interface To The final location of the destination interface , The change process of animation execution ;
required this.child : Can't be empty , ordinary Widget Components , Hero Animated components ;
Hero Animation can realize radial animation , Radial animation refers to the animation of variable component shape , If a circle changes to a square , Square becomes triangle ;
Hero Radial animation And The difference between ordinary animation is whether it is set createRectTween Parameters ;
One 、 Round square components
Components with round and square changes : The component can change from round to square according to different parameters , Or the change from square to round ;
/// Hero Components , Radial animation extension /// This component is mainly used for cutting components class OvalRectWidget extends StatelessWidget {
/// The cutting size here clipRectSize Maximum radius / 2 The square root of Multiplied by 2 const OvalRectWidget({
Key key, this.maxRadius, this.child}) : clipRectSize = 2.0 * (maxRadius / math.sqrt2), super(key: key); // Maximum radius value final double maxRadius; /// This value needs to be calculated dynamically final clipRectSize; final Widget child; /// Special attention is paid here to the circular clipping component /// If the width and height of the whole component are maxRadius , /// The width and height of the inner square component is 2.0 * (maxRadius / math.sqrt2) /// And the square component is displayed in the center /// Then the four vertices of the square component are exactly at the cutting radius of the circular component /// That is, the square component is completely displayed , Not cut to @override Widget build(BuildContext context) {
/// Layout clipping components , You can crop the layout into a circle return ClipOval( /// Components that can be used to constrain layout size /// The central display here is the key , If not centered , Finally, it is round child: Center( child: SizedBox( width: clipRectSize, height: clipRectSize, /// Components for clipping rounded rectangles child: ClipRect( child: child, ), ), ), ); }}
Component shape display analysis :
① Square cutting component : ClipOval Component area is Red The position of the rectangle , Its clipping area is the location of blue components , If there happens to be a square component ClipRect In the orange area below , Then the square component just evades the red area around it ClipOval Operation of clipping ; The components shown are still square ;
② Circular clipping component : If ClipOval Circular clipping component ( Red ) And ClipRect Square cutting component ( Orange ) The positions overlap , Then the square cutting component must be cut into a circle ;
The above two components are Hero The main function component of radial animation , Before the animation is executed , The components are round , After execution, the component is square , This is what changed the outer layer ClipOval The size of the component , Cause the shape to change ;
Two 、 Create a page 1 The components of ( Hero Components 1 )
page 1 Of Hero The component displays a circular , Jump to page 2 after , identical tag Of Hero The component displays square ;
control OvalRectWidget Is it round or square , Mainly control OvalRectWidget The width and height of the component , The width and height settings set here , Equivalent to " ② Circular clipping component " situation , The whole component is cut into circular components ;
Create a page 1 The components of :
/// Create in the interface 1 The icon displayed , Click to jump to the interface 2 /// The core component of the page is Hero Components , And it's 3 individual Widget _buildFirstPagWidget( BuildContext context, String imageName, String description) {
return Container( /// Interface 1 Shown in Hero Components are small icons /// The size of the icon is twice the radius width: minRadius * 2.0, height: minRadius * 2.0, /// The core of the main interface Hero Animation child: Hero( /// This is a Hero Radial animation and Standards Hero The difference between animation /// Without this animation , The intermediate process will become an ellipse createRectTween: _createRectTween, /// Hero Animated tags tag: imageName, child: OvalRectWidget( maxRadius: maxRadius, /// The innermost layer shows the network image component child: ImageWidget( /// Set the network picture address imageUrl: imageName, // Set click event onTap: () {
/// Click to jump to the new interface Navigator.of(context).push(PageRouteBuilder<void>(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
// Create a RoutePageBuilder return AnimatedBuilder( animation: animation, builder: (context, child) {
/// Set the transparency component return Opacity( /// Current transparency value , Value 0.0 ~ 1.0 opacity: opacityCurve.transform(animation.value), // Mainly display components that use transparency control // page 2 Components child: _buildSecondPageWidget(context, imageName, description), ); }); })); }, ), ), ), ); }
3、 ... and 、 Create a page 2 The components of ( Hero Components 2 )
page 1 Of Hero The component displays a circular , Jump to page 2 after , identical tag Of Hero The component displays square ;
control OvalRectWidget Is it round or square , Mainly control OvalRectWidget The width and height of the component , The width and height set here is equivalent to the above " ① Square cutting component " Set up , The whole component is not trimmed to , The square component is shown ;
Create a page 2 The components of :
/// Create a page 2 , This is the page to jump to after clicking /// The three parameters are : Context , Image name , Page description /// The core component of the page is Hero Components , Only 1 individual static Widget _buildSecondPageWidget( BuildContext context, String imageName, String description) {
return Container( color: Theme.of(context).canvasColor, child: Center( child: Card( /// Set the shadow size of card layout elevation: 8, /// The picture and its description are displayed in the card layout child: Column( /// In the direction of the spindle , That is, the vertical direction , How much space should it take /// Colum The spindle direction is vertical /// Row The spindle direction is horizontal mainAxisSize: MainAxisSize.min, children: [ SizedBox( /// The width and height of components that constrain the size of the layout are defined as twice the maximum radius width: maxRadius * 2, height: maxRadius * 2, /// The core Hero Components child: Hero( /// Create radial animation /// Without this animation , The intermediate process will become an ellipse createRectTween: _createRectTween, /// Hero Animated tags ID tag: imageName, /// Hero Animated components child: OvalRectWidget( /// The radius here is set to the maximum radius , maxRadius: maxRadius, /// The innermost layer shows the network image component child: ImageWidget( imageUrl: imageName, onTap: () {
/// Click to close the current page Navigator.of(context).pop(); }, ), ), ), ), /// Picture description text Text( // Set text content description, // Set text style , bold style: TextStyle(fontWeight: FontWeight.bold), textScaleFactor: 3.0, ), /// White space , No practical significance const SizedBox( height: 16, ), ], ), ), ), ); }
Four 、 Complete code example
Complete code example :
import 'package:flutter/material.dart';import 'package:flutter/scheduler.dart' show timeDilation;import 'dart:math' as math;void main() {
runApp(MaterialApp( // The essence of this component is StatelessWidget Component subclass home: RadialHeroAnimation(), ));}/// Hero Components , This component is available on both pages before and after jump class ImageWidget extends StatelessWidget {
/// Construction method const ImageWidget({
Key key, this.imageUrl, this.onTap}) : super(key: key); /// Hero Animation related ID , Through this identification /// Identify two Hero Animation transition between components /// At the same time, the string is also the image url network address final String imageUrl; /// Callback event after clicking final VoidCallback onTap; @override Widget build(BuildContext context) {
return Material( /// Get theme color , And set the transparency to 0.25 color: Colors.green, /// Button child: InkWell( /// Button click event onTap: onTap, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints size) {
return Image.network( imageUrl, fit: BoxFit.contain, ); }, ), ), ); }}/// Hero Components , Radial animation extension /// This component is mainly used for cutting components class OvalRectWidget extends StatelessWidget {
/// The cutting size here clipRectSize Maximum radius / 2 The square root of Multiplied by 2 const OvalRectWidget({
Key key, this.maxRadius, this.child}) : clipRectSize = 2.0 * (maxRadius / math.sqrt2), super(key: key); // Maximum radius value final double maxRadius; /// This value needs to be calculated dynamically final clipRectSize; final Widget child; /// Special attention is paid here to the circular clipping component /// If the width and height of the whole component are maxRadius , /// The width and height of the inner square component is 2.0 * (maxRadius / math.sqrt2) /// And the square component is displayed in the center /// Then the four vertices of the square component are exactly at the cutting radius of the circular component /// That is, the square component is completely displayed , Not cut to @override Widget build(BuildContext context) {
/// Layout clipping components , You can crop the layout into a circle return ClipOval( /// Components that can be used to constrain layout size /// The central display here is the key , If not centered , Finally, it is round child: Center( child: SizedBox( width: clipRectSize, height: clipRectSize, /// Components for clipping rounded rectangles child: ClipRect( child: child, ), ), ), ); }}class RadialHeroAnimation extends StatelessWidget {
/// Minimum radius /// When using this radius as the component size , Components are cut into circles static const double minRadius = 32.0; /// Maximum radius /// When using this radius as the component size , The components are cut into squares static const double maxRadius = 128.0; /// Animated differential static const opacityCurve = Interval(0.0, 0.75, curve: Curves.fastOutSlowIn); /// Create radial animation static RectTween _createRectTween(Rect begin, Rect end) {
/// MaterialRectCenterArcTween It is an auxiliary class that changes from square to circle return MaterialRectCenterArcTween(begin: begin, end: end); } /// Create a page 2 , This is the page to jump to after clicking /// The three parameters are : Context , Image name , Page description /// The core component of the page is Hero Components , Only 1 individual static Widget _buildSecondPageWidget( BuildContext context, String imageName, String description) {
return Container( color: Theme.of(context).canvasColor, child: Center( child: Card( /// Set the shadow size of card layout elevation: 8, /// The picture and its description are displayed in the card layout child: Column( /// In the direction of the spindle , That is, the vertical direction , How much space should it take /// Colum The spindle direction is vertical /// Row The spindle direction is horizontal mainAxisSize: MainAxisSize.min, children: [ SizedBox( /// The width and height of components that constrain the size of the layout are defined as twice the maximum radius width: maxRadius * 2, height: maxRadius * 2, /// The core Hero Components child: Hero( /// Create radial animation /// Without this animation , The intermediate process will become an ellipse createRectTween: _createRectTween, /// Hero Animated tags ID tag: imageName, /// Hero Animated components child: OvalRectWidget( /// The radius here is set to the maximum radius , maxRadius: maxRadius, /// The innermost layer shows the network image component child: ImageWidget( imageUrl: imageName, onTap: () {
/// Click to close the current page Navigator.of(context).pop(); }, ), ), ), ), /// Picture description text Text( // Set text content description, // Set text style , bold style: TextStyle(fontWeight: FontWeight.bold), textScaleFactor: 3.0, ), /// White space , No practical significance const SizedBox( height: 16, ), ], ), ), ), ); } /// Create in the interface 1 The icon displayed , Click to jump to the interface 2 /// The core component of the page is Hero Components , And it's 3 individual Widget _buildFirstPagWidget( BuildContext context, String imageName, String description) {
return Container( /// Interface 1 Shown in Hero Components are small icons /// The size of the icon is twice the radius width: minRadius * 2.0, height: minRadius * 2.0, /// The core of the main interface Hero Animation child: Hero( /// This is a Hero Radial animation and Standards Hero The difference between animation /// Without this animation , The intermediate process will become an ellipse createRectTween: _createRectTween, /// Hero Animated tags tag: imageName, child: OvalRectWidget( maxRadius: maxRadius, /// The innermost layer shows the network image component child: ImageWidget( /// Set the network picture address imageUrl: imageName, // Set click event onTap: () {
/// Click to jump to the new interface Navigator.of(context).push(PageRouteBuilder<void>(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
// Create a RoutePageBuilder return AnimatedBuilder( animation: animation, builder: (context, child) {
/// Set the transparency component return Opacity( /// Current transparency value , Value 0.0 ~ 1.0 opacity: opacityCurve.transform(animation.value), // Mainly display components that use transparency control // page 2 Components child: _buildSecondPageWidget(context, imageName, description), ); }); })); }, ), ), ), ); } @override Widget build(BuildContext context) {
/// Time expansion coefficient , Used to reduce the running speed of animation /// 1.0 Is the standard speed timeDilation = 5.0; /// The main interface displays content return Scaffold( appBar: AppBar( title: Text("Hero Radial animation demonstration "), ), body: Container( padding: EdgeInsets.all(32), alignment: FractionalOffset.bottomLeft, /// Horizontal list display 3 An icon child: Row( /// arrangement : Bisector space mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildFirstPagWidget(context, "https://img-blog.csdnimg.cn/20210330094257242.png", " Queen bee "), _buildFirstPagWidget(context, "https://img-blog.csdnimg.cn/20210330093526559.png", " The bees "), _buildFirstPagWidget(context, "https://img-blog.csdnimg.cn/2021033009353553.png", " worker bee "), ], ), ), ); }}
Running effect :
5、 ... and 、 Related resources
Reference material :
- Flutter Official website : https://flutter.dev/
- Flutter Plug in download address : https://pub.dev/packages
- Flutter Developing documents : https://flutter.cn/docs ( Strongly recommend )
- official GitHub Address : https://github.com/flutter
- Flutter The Chinese community : https://flutter.cn/
- Flutter Practical tutorial : https://flutter.cn/docs/cookbook
- Flutter CodeLab : https://codelabs.flutter-io.cn/
- Dart Chinese document : https://dart.cn/
- Dart Developer website : https://api.dart.dev/
- Flutter Chinese net : https://flutterchina.club/ , http://flutter.axuer.com/docs/
- Flutter Related issues : https://flutterchina.club/faq/ ( It is recommended to watch it at the introductory stage )
- GitHub Upper Flutter Open source examples : https://download.csdn.net/download/han1202012/15989510
- Flutter Practical e-books : https://book.flutterchina.club/chapter1/
Important topics :
- Flutter Animation reference documentation : https://flutterchina.club/animations/
Blog source download :
GitHub Address : https://github.com/han1202012/flutter_animation ( Keep updating with the progress of the blog , There may not be the source code of this blog )
Blog source snapshot : https://download.csdn.net/download/han1202012/16245277 ( The source code snapshot of this blog , You can find the source code of this blog )
边栏推荐
- Network security - virus
- Main features of transport layer TCP and TCP connection
- [camera topic] how to save OTP data in user-defined nodes
- Network security - cracking system passwords
- 疫情当头,作为Leader如何进行团队的管理?| 社区征文
- [keil5 debugging] debug is stuck in reset_ Handler solution
- Query product cases - page rendering data
- 小程序开发的部分功能
- [shutter] animation animation (basic process of shutter animation | create animation controller | create animation | set value listener | set state listener | use animation values in layout | animatio
- [QT] encapsulation of custom controls
猜你喜欢
【數據挖掘】任務6:DBSCAN聚類
[camera topic] how to save OTP data in user-defined nodes
STM32 - GPIO input / output mode
Telecom Customer Churn Prediction challenge
Performance test | script template sorting, tool sorting and result analysis
Rockchip3399 start auto load driver
Tâche 6: regroupement DBSCAN
ByteDance data Lake integration practice based on Hudi
[Appendix 6 Application of reflection] Application of reflection: dynamic agent
Smart management of Green Cities: Digital twin underground integrated pipe gallery platform
随机推荐
网络安全-动态路由协议RIP
[untitled]
Technology sharing | Frida's powerful ability to realize hook functions
Why can't the start method be called repeatedly? But the run method can?
Analysis, use and extension of open source API gateway apisex
云原生题目整理(待更新)
The testing process that software testers should know
[camera topic] how to save OTP data in user-defined nodes
[technology development-23]: application of DSP in future converged networks
A 30-year-old software tester, who has been unemployed for 4 months, is confused and doesn't know what to do?
自定义组件、使用npm包、全局数据共享、分包
Network security NAT network address translation
Network security - firewall
Problems encountered in small program development of dark horse shopping mall
STM32 - Application of external interrupt induction lamp
网络安全-破解系统密码
小程序开发黑马购物商城中遇到的问题
[AUTOSAR cantp] -2.11-uds diagnostic response frame data segment data padding data filling and data optimization data optimization (Theory + configuration)
查询商品案例-页面渲染数据
[data mining] task 6: DBSCAN clustering