## 自定義路由切換動畫
Material庫中提供了一個MaterialPageRoute,它可以使用和平臺風格一致的路由切換動畫,如在iOS上會左右滑動切換,而在Android上會上下滑動切換。如果在Android上也想使用左右切換風格,可以直接使用CupertinoPageRoute, 如:
```
Navigator.push(context, CupertinoPageRoute(
builder: (context){
return PageB(); //路由B
}
));
```
如果想自定義路由切換動畫,可以使用PageRouteBuilder,例如我們想以漸隱漸入動畫來實現路由過渡:
```
Navigator.push(context, PageRouteBuilder(
transitionDuration: Duration(milliseconds: 500), //動畫時間為500毫秒
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
return new FadeTransition( //使用漸隱漸入過渡,
opacity: animation,
child: PageB() //路由B
);
}));
}),
```
我們可以看到`pageBuilder` 有一個animation參數,這是Flutter路由管理器提供的,在路由切換時`pageBuilder`在每個動畫幀都會被回調,因此我們可以通過animation對象來自定義過渡動畫。
無論是MaterialPageRoute、CupertinoPageRoute,還是PageRouteBuilder,它們都繼承自PageRoute類,而PageRouteBuilder其實只是PageRoute的一個包裝,我們可以直接繼承PageRoute類來實現自定義路由,上面的例子可以通過如下方式實現:
1. 定義一個路由類FadeRoute
```
class FadeRoute extends PageRoute {
FadeRoute({
@required this.builder,
this.transitionDuration = const Duration(milliseconds: 300),
this.opaque = true,
this.barrierDismissible = false,
this.barrierColor,
this.barrierLabel,
this.maintainState = true,
});
final WidgetBuilder builder;
@override
final Duration transitionDuration;
@override
final bool opaque;
@override
final bool barrierDismissible;
@override
final Color barrierColor;
@override
final String barrierLabel;
@override
final bool maintainState;
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) => builder(context);
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return FadeTransition(
opacity: animation,
child: builder(context),
);
}
}
```
2. 使用FadeRoute
```
Navigator.push(context, FadeRoute(builder: (context) {
return PageB();
}));
```
雖然上面的兩種方法都可以實現自定義切換動畫,但實際使用時應考慮優先使用PageRouteBuilder,這樣無需定義一個新的路由類,使用起來會比較方便。但是有些時候PageRouteBuilder是不能滿足需求的,例如在應用過渡動畫時我們需要讀取當前路由的一些屬性,這時就只能通過繼承PageRoute的方式了,舉個例子,假如我們只想在打開新路由時應用動畫,而在返回時不使用動畫,那么我們在構建過渡動畫時就必須判斷當前路由`isActive`屬性是否為true,代碼如下:
```
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
//當前路由被激活,是打開新路由
if(isActive) {
return FadeTransition(
opacity: animation,
child: builder(context),
);
}else{
//是返回,則不應用過渡動畫
return Padding(padding: EdgeInsets.zero);
}
}
```
關于路由參數的詳細信息讀者可以自行查閱API文檔,比較簡單,不再贅述。
- 緣起
- 起步
- 移動開發技術簡介
- Flutter簡介
- 搭建Flutter開發環境
- 常見配置問題
- Dart語言簡介
- 第一個Flutter應用
- 計數器示例
- 路由管理
- 包管理
- 資源管理
- 調試Flutter APP
- Dart線程模型及異常捕獲
- 基礎Widgets
- Widget簡介
- 文本、字體樣式
- 按鈕
- 圖片和Icon
- 單選框和復選框
- 輸入框和表單
- 布局類Widgets
- 布局類Widgets簡介
- 線性布局Row、Column
- 彈性布局Flex
- 流式布局Wrap、Flow
- 層疊布局Stack、Positioned
- 容器類Widgets
- Padding
- 布局限制類容器ConstrainedBox、SizeBox
- 裝飾容器DecoratedBox
- 變換Transform
- Container容器
- Scaffold、TabBar、底部導航
- 可滾動Widgets
- 可滾動Widgets簡介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滾動監聽及控制ScrollController
- 功能型Widgets
- 導航返回攔截-WillPopScope
- 數據共享-InheritedWidget
- 主題-Theme
- 事件處理與通知
- 原始指針事件處理
- 手勢識別
- 全局事件總線
- 通知Notification
- 動畫
- Flutter動畫簡介
- 動畫結構
- 自定義路由過渡動畫
- Hero動畫
- 交錯動畫
- 自定義Widget
- 自定義Widget方法簡介
- 通過組合現有Widget實現
- 實例:TurnBox
- CustomPaint與Canvas
- 實例:圓形漸變進度條(自繪)
- 文件操作與網絡請求
- 文件操作
- Http請求-HttpClient
- Http請求-Dio package
- 實例:Http分塊下載
- WebSocket
- 使用Socket API
- Json轉Model
- 包與插件
- 開發package
- 插件開發:平臺通道簡介
- 插件開發:實現Android端API
- 插件開發:實現IOS端API
- 系統能力調用
- 國際化
- 讓App支持多語言
- 實現Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系統
- Element和BuildContext
- RenderObject與RenderBox
- Flutter從啟動到顯示