[- Flutter福利篇 -] Hero转场组件共享 — 附赠-路由动画工具类
时间:2022-07-27
本文章向大家介绍[- Flutter福利篇 -] Hero转场组件共享 — 附赠-路由动画工具类,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最近比较忙,很少发文章了。今天抽空把Hero的转场组件共享说一下 顺便发个转场的动画福利类,可以定义转场的时间,曲线,别客气,随便拿去用。 废话不多说,先看图:
- 1.透明:
FadeRouter
- 2.缩放:
ScaleRouter
- 3.旋转:
RotateRouter
- 4.透明+缩放+旋转
- 5.右--->左:
Right2LeftRouter
- 6.左--->右:
Left2RightRouter
- 7.上--->下:
Top2BottomRouter
- 8.下--->上:
Bottom2TopRouter
Hero元素共享
也许上面吸引你的不是界面跳转的动画,而是那个头像神奇般的轨迹。下面就来说一下如何实现。
起始页:OriginPage
class OriginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var hero= Hero(//----定义一个Hero,并添加tag标签,此中组件共享
tag: 'user-head',
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Image.asset(
"images/mani.jpg",width: 60,height: 60,fit: BoxFit.cover,
),
),
);
var container= Container(//容器,没啥好说的
alignment: Alignment(-0.8, -0.8),
child: hero,
width: 250,
height: 250*0.618,
decoration: BoxDecoration(//添加渐变色
gradient: LinearGradient(colors: [Colors.red.withAlpha(99),Colors.yellow.withAlpha(189),Colors.green.withAlpha(88),Colors.blue.withAlpha(230)])
),);
return Scaffold(
body: Center(//点击跳转
child: GestureDetector(child: Card(elevation:5,child:container ,),onTap: (){
_toNext(context);
},),
),
);
}
void _toNext(context) {//跳转路由
Navigator.push(
context,
// FadeRouter(child:TargetPage()),
// ScaleRouter(child:TargetPage()),
// RotateRouter(child:TargetPage()),
// ScaleFadeRotateRouter(child:TargetPage()),
// Right2LeftRouter(child:TargetPage()),
// Left2RightRouter(child:TargetPage()),
// Top2BottomRouter(child:TargetPage()),
Bottom2TopRouter(child:TargetPage()),//跳转+动画
);
}
}
目标页:TargetPage
class TargetPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var hero=Hero(//----定义一个Hero,为其添加标签,两个标签相同,则可以共享
tag: 'user-head',
child: Padding(
padding: EdgeInsets.all(16.0),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 72.0,
backgroundImage: AssetImage(
"images/mani.jpg",
),
),
),
);
var touch=InkWell(onTap: (){
Navigator.of(context).pop();
},child: hero,);
return Scaffold(
appBar: AppBar(leading:touch ,),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.red.withAlpha(99),Colors.yellow.withAlpha(189),Colors.green.withAlpha(88),Colors.blue.withAlpha(230)])
),
),
);
}
}
关于createRectTween属性
在回调中会给两个初始和结束的两个矩形,可以进行矩形动画来控制共享组件的区域,如下图在目标页:
var height=MediaQuery.of(context).size.height;
var width=MediaQuery.of(context).size.width;
var size=min(height,width);
var hero=Hero(//----定义一个Hero,为其添加标签,两个标签相同,则可以共享
createRectTween: ((r1,r2){
return RectTween(begin: Rect.fromLTWH(size/2,0, size, size),end: r2);
}),
另外还有个要点:同一页面不能出现多处同名Hero
福利时间:路由动画工具
使用方法看上面的路由跳转处,当然你也可以根据下面的定制更酷炫的跳转效果。
import 'package:flutter/cupertino.dart';
//缩放路由动画
class ScaleRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
ScaleRouter({this.child, this.duration_ms = 500,this.curve=Curves.fastOutSlowIn})
: super(
pageBuilder: (context, animation, secondaryAnimation) => child,
transitionDuration: Duration(milliseconds: duration_ms),
transitionsBuilder: (context, a1, a2, child) =>
ScaleTransition(
scale: Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child,
),
);
}
//渐变透明路由动画
class FadeRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
FadeRouter({this.child, this.duration_ms = 500,this.curve=Curves.fastOutSlowIn})
: super(
pageBuilder: (context, animation, secondaryAnimation) => child,
transitionDuration: Duration(milliseconds: duration_ms),
transitionsBuilder: (context, a1, a2, child) =>
FadeTransition(
opacity: Tween(begin: 0.1, end: 1.0).animate(
CurvedAnimation(parent: a1, curve:curve,)),
child: child,
));
}
//旋转路由动画
class RotateRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
RotateRouter({this.child, this.duration_ms = 500,this.curve=Curves.fastOutSlowIn})
: super(
pageBuilder: (context, animation, secondaryAnimation) => child,
transitionDuration: Duration(milliseconds: duration_ms),
transitionsBuilder: (context, a1, a2, child) =>
RotationTransition(
turns: Tween(begin: 0.1, end: 1.0).animate(
CurvedAnimation(parent: a1, curve:curve,)),
child: child,
));
}
//右--->左
class Right2LeftRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
Right2LeftRouter({this.child,this.duration_ms=500,this.curve=Curves.fastOutSlowIn})
:super(
transitionDuration:Duration(milliseconds: duration_ms),
pageBuilder:(ctx,a1,a2){return child;},
transitionsBuilder:(ctx,a1,a2,Widget child,) {
return SlideTransition(
position: Tween(
begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//左--->右
class Left2RightRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
List mapper;
Left2RightRouter({this.child,this.duration_ms=500,this.curve=Curves.fastOutSlowIn})
:assert(true),super(
transitionDuration:Duration(milliseconds: duration_ms),
pageBuilder:(ctx,a1,a2){return child;},
transitionsBuilder:(ctx,a1,a2,Widget child,) {
return SlideTransition(
position: Tween(
begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//上--->下
class Top2BottomRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
Top2BottomRouter({this.child,this.duration_ms=500,this.curve=Curves.fastOutSlowIn})
:super(
transitionDuration:Duration(milliseconds: duration_ms),
pageBuilder:(ctx,a1,a2){return child;},
transitionsBuilder:(ctx,a1,a2,Widget child,) {
return SlideTransition(
position: Tween(
begin: Offset(0.0,-1.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//下--->上
class Bottom2TopRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
Bottom2TopRouter({this.child,this.duration_ms=500,this.curve=Curves.fastOutSlowIn})
:super(
transitionDuration:Duration(milliseconds: duration_ms),
pageBuilder:(ctx,a1,a2){return child;},
transitionsBuilder:(ctx,a1,a2,Widget child,) {
return SlideTransition(
position: Tween(
begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//缩放+透明+旋转路由动画
class ScaleFadeRotateRouter extends PageRouteBuilder {
final Widget child;
final int duration_ms;
final Curve curve;
ScaleFadeRotateRouter({this.child, this.duration_ms = 500,this.curve=Curves.fastOutSlowIn}) : super(
transitionDuration: Duration(milliseconds: duration_ms),
pageBuilder: (ctx, a1, a2)=>child,//页面
transitionsBuilder: (ctx, a1, a2, Widget child,) {//构建动画
return RotationTransition(//旋转动画
turns: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
parent: a1,
curve: curve,
)),
child: ScaleTransition(//缩放动画
scale: Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: FadeTransition(opacity://透明度动画
Tween(begin: 0.5, end: 1.0).animate(CurvedAnimation(parent: a1, curve: curve)),
child: child,),
),
);
});
}
//无动画
class NoAnimRouter extends PageRouteBuilder {
final Widget page;
NoAnimRouter(this.page)
: super(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionDuration: Duration(milliseconds: 0),
transitionsBuilder:
(context, animation, secondaryAnimation, child) => child);
}
- 你绝对想不到,数据地图还能这么玩~
- TensorFlow从0到1 - 17 - Step By Step上手TensorBoard
- 深度强化学习-Actor-Critic算法原理和实现
- 深度强化学习-Policy Gradient基本实现
- TensorFlow从0到1 - 7 - TensorFlow线性回归的参数溢出之坑
- 买卖股票算法题的后续!
- 一个例子教你如何与出题人斗智斗勇
- 用数据来聊聊国产电影~
- 如何买卖股票?不要慌,我有妙招!
- 2017.11.7解题报告
- TensorFlow从0到1 - 11 - 74行Python实现手写体数字识别
- 让priority_queue支持小根堆的几种方法
- 一招解决4道leetcode hard题,动态规划在字符串匹配问题中的应用
- 细数Python中的数据类型以及他们的方法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Discourse 如何不使用 Let’s Encrypt 而使用 CA 签名的密钥进行安装
- 3分钟短文:Laravel slug,让你的url地址更“好记”
- Qt音视频开发28-Onvif信息获取
- CentOS 8 启用 NTP 服务
- Discourse 如何使用命令行方式进行恢复
- CentOS 8 Apache 启用 SSL
- leetcode栈之二叉树的前序遍历
- 前端学数据结构与算法(七): 从零实现优先队列-堆及其应用
- 前端学数据结构与算法(六):二叉树的四种遍历方式及其应用
- 前端学数据结构与算法(五):理解二叉树特性及从零实现二叉搜索树
- 前端学数据结构与算法(四):理解递归及拿力扣链表题目练手
- 前端学数据结构与算法(三):链表为什么能和数组相提并论?用链表实现数组bettle下
- 前端学数据结构与算法(二):数组的操作特性与栈的应用
- 前端学数据结构与算法(一):不会复杂度分析,算法等于白学
- 高可扩展性系统的设计