最近比較忙,不多發文章了。今天抽空把Hero的轉場組件共享說一下
順便發個轉場的動畫福利類,能夠定義轉場的時間,曲線,別客氣,隨便拿去用。
廢話很少說,先看圖:bash
FadeRouter
ScaleRouter
RotateRouter
Right2LeftRouter
Left2RightRouter
Top2BottomRouter
Bottom2TopRouter
也許上面吸引你的不是界面跳轉的動畫,而是那個頭像神奇般的軌跡。下面就來講一下如何實現。微信
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()),//跳轉+動畫
);
}
}
複製代碼
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)])
),
),
);
}
}
複製代碼
在回調中會給兩個初始和結束的兩個矩形,能夠進行矩形動畫來控制共享組件的區域,以下圖在目標頁:app
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
less
使用方法看上面的路由跳轉處,固然你也能夠根據下面的定製更酷炫的跳轉效果。ide
import 'package:flutter/cupertino.dart';
//縮放路由動畫
class ScaleRouter<T> extends PageRouteBuilder<T> {
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<T> extends PageRouteBuilder<T> {
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<T> extends PageRouteBuilder<T> {
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<T> extends PageRouteBuilder<T> {
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<Offset>(
begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//左--->右
class Left2RightRouter<T> extends PageRouteBuilder<T> {
final Widget child;
final int duration_ms;
final Curve curve;
List<int> 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<Offset>(
begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//上--->下
class Top2BottomRouter<T> extends PageRouteBuilder<T> {
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<Offset>(
begin: Offset(0.0,-1.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//下--->上
class Bottom2TopRouter<T> extends PageRouteBuilder<T> {
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<Offset>(
begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0),).animate(
CurvedAnimation(parent: a1, curve: curve)),
child: child
);
});
}
//縮放+透明+旋轉路由動畫
class ScaleFadeRotateRouter<T> extends PageRouteBuilder<T> {
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<T> extends PageRouteBuilder<T> {
final Widget page;
NoAnimRouter(this.page)
: super(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionDuration: Duration(milliseconds: 0),
transitionsBuilder:
(context, animation, secondaryAnimation, child) => child);
}
複製代碼
本文到此接近尾聲了,若是想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品;若是想細細探究它,那就跟隨個人腳步,完成一次Flutter之旅。
另外本人有一個Flutter微信交流羣,歡迎小夥伴加入,共同探討Flutter的問題,本人微信號:zdl1994328
,期待與你的交流與切磋。工具