現在Flutter的路由效果已經非常不錯了,能滿足大部分App的需求,但是誰不希望自己的App更酷更炫那,下面介紹幾個酷炫的路由動畫。
其實路由動畫的原理很簡單,就是重寫並繼承PageRouterBuilder
這個類里的transitionsBuilder
方法。
不過這個方法還是有很多寫法的,通過寫法的不同,產生的動畫效果也有所不同。
1、漸隱漸現的動畫效果
先編寫一個主入口方法,還是最簡單的格式,只不過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,這個你要跟網頁區分開)。有了兩個頁面就可以實現路由跳轉了。
這里我們先用普通路由代替,看一看效果。
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(), ), ) ); } }
上面代碼中有一個新知識點,需要學習一下:
AppBar Widger的 elevation 屬性:這個值是AppBar 滾動時的融合程度,一般有滾動時默認是4.0,現在我們設置成0.0,就是和body完全融合了。
寫完這個頁面代碼后,已經可以進行最基本的導航了,但是並沒有什么酷炫的動畫。
自定義CustomRoute Widget
這個就是要自定義的路由方法,自定義首先要繼承於通用的路由的構造器類PageRouterBuilder
。繼承之后重寫父類的CustomRoute
構造方法。
構造方法可以簡單理解為:只要以調用這個類或者說是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())); },
寫完代碼,我們已經可以看到在切換路由時有了漸隱漸現的動畫效果。
2、縮放的動畫效果
修改transitionsBuilder下{ }里的內容
//縮放的動畫效果 return ScaleTransition( scale: Tween(begin: 0.0,end: 1.0).animate(CurvedAnimation( parent: animation1, curve: Curves.fastOutSlowIn, )), child: child, );
3、旋轉+縮放動畫效果
旋轉+縮放的思路是在一個路由動畫里的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, ), );
4、左側滑動進入退出動畫
其實用的做多的還是左右滑動路由動畫,其實實現起來也是非常簡單,直接使用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, );