如今Flutter的路由效果已經很是不錯了,能知足大部分App的需求,可是誰不但願本身的App更酷更炫那,下面介紹幾個酷炫的路由動畫。app
其實路由動畫的原理很簡單,就是重寫並繼承PageRouterBuilder
這個類裏的transitionsBuilder
方法。less
不過這個方法仍是有不少寫法的,經過寫法的不一樣,產生的動畫效果也有所不一樣。ide
先編寫一個主入口方法,仍是最簡單的格式,只不過home屬性,使用的RouterFirst的組件是咱們自定義的,須要咱們再次編寫。入口文件的代碼以下:學習
import 'package:flutter/material.dart'; import 'pages.dart'; void main()=>runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title:'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home:RouterFirst() ); } }
而後是pages.dart,這個文件就是生成了兩個頁面(Flutter裏的頁面也是Widget,這個你要跟網頁區分開)。有了兩個頁面就能夠實現路由跳轉了。動畫
這裏咱們先用普通路由代替,看一看效果。ui
import 'package:flutter/material.dart'; class RouterFirst extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.red, //背景色 appBar: AppBar( title: Text('FirstPage',style: TextStyle(fontSize: 36.0)), elevation: 4.0, //0-4 和下面body的融合程度,0是不顯示分隔狀態,不寫默認是4 ), body: Center( child: MaterialButton( child: Icon( Icons.navigate_next, color: Colors.white, size: 64.0 ), onPressed: (){ Navigator.of(context).push(MaterialPageRoute(builder:(BuildContext context){ return RouterSecond(); })); }, ), ), ); } } class RouterSecond extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.lightBlue, appBar: AppBar( title: Text('SecondPage',style:TextStyle(fontSize:36.0),), backgroundColor: Colors.lightBlue, leading:Container(), elevation: 0.0, ), body:Center( child: MaterialButton( child: Icon( Icons.navigate_before, color:Colors.white, size:64.0 ), onPressed: ()=>Navigator.of(context).pop(), ), ) ); } }
上面代碼中有一個新知識點,須要學習一下:this
AppBar Widger的 elevation 屬性:這個值是AppBar 滾動時的融合程度,通常有滾動時默認是4.0,如今咱們設置成0.0,就是和body徹底融合了。spa
寫完這個頁面代碼後,已經能夠進行最基本的導航了,可是並無什麼酷炫的動畫。3d
這個就是要自定義的路由方法,自定義首先要繼承於通用的路由的構造器類PageRouterBuilder
。繼承以後重寫父類的CustomRoute
構造方法。code
構造方法能夠簡單理解爲:只要以調用這個類或者說是Widget,構造方法裏的全部代碼就執行了。
代碼以下:
class CustomRoute extends PageRouteBuilder{ final Widget widget; //構造方法 CustomRoute(this.widget) :super( transitionDuration:Duration(seconds: 2), //過渡時間 pageBuilder:( //構造器 BuildContext context, Animation<double> animation1, Animation<double> animation2, ){ return widget; }, transitionsBuilder:( BuildContext context, Animation<double> animation1, Animation<double> animation2, Widget child ){ return FadeTransition( opacity: Tween(begin: 0.0,end: 1.0) .animate(CurvedAnimation( parent: animation1, curve: Curves.fastOutSlowIn, //動畫曲線 )), child: child, ); } ); }
FadeTransition:漸隱漸現過渡效果,主要設置opactiy(透明度)屬性,值是0.0-1.0。
animate :動畫的樣式,通常使用動畫曲線組件(CurvedAnimation)。
curve: 設置動畫的節奏,也就是常說的曲線,Flutter準備了不少節奏,經過改變更畫取消能夠作出不少不一樣的效果。
transitionDuration:設置動畫持續的時間,建議再1和2之間。
最後要把上面onPressed代碼修改下:
onPressed: (){ // Navigator.of(context).push(MaterialPageRoute(builder:(BuildContext context){ // return RouterSecond(); // })); Navigator.of(context).push(CustomRoute(RouterSecond())); },
寫完代碼,咱們已經能夠看到在切換路由時有了漸隱漸現的動畫效果。
修改transitionsBuilder下{ }裏的內容
//縮放的動畫效果 return ScaleTransition( scale: Tween(begin: 0.0,end: 1.0).animate(CurvedAnimation( parent: animation1, curve: Curves.fastOutSlowIn, )), child: child, );
旋轉+縮放的思路是在一個路由動畫裏的child屬性裏再加入一個動畫,讓兩個動畫同時執行。來看詳細代碼:
//旋轉+縮放動畫效果 return RotationTransition( turns: Tween(begin: 0.0,end: 1.0).animate(CurvedAnimation( parent:animation1, curve: Curves.fastOutSlowIn )), child: ScaleTransition( scale: Tween(begin: 0.0,end: 1.0).animate(CurvedAnimation( parent: animation1, curve: Curves.fastOutSlowIn )), child: child, ), );
其實用的作多的仍是左右滑動路由動畫,其實實現起來也是很是簡單,直接使用SlideTransition
就能夠了。
//左側滑動進入退出 return SlideTransition( position: Tween<Offset>( begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0) ).animate(CurvedAnimation( parent: animation1, curve:Curves.fastOutSlowIn )), child: child, );