Flutter實(shí)戰(zhàn) 自定義路由切換動畫

2021-03-08 18:01 更新

#9.3 自定義路由切換動畫

我們在第二章“路由管理”一節(jié)中講過:Material 組件庫中提供了一個MaterialPageRoute組件,它可以使用和平臺風(fēng)格一致的路由切換動畫,如在 iOS 上會左右滑動切換,而在 Android 上會上下滑動切換?,F(xiàn)在,我們?nèi)绻?Android 上也想使用左右切換風(fēng)格,該怎么做?一個簡單的作法是可以直接使用CupertinoPageRoute,如:

  1. Navigator.push(context, CupertinoPageRoute(
  2. builder: (context)=>PageB(),
  3. ));

CupertinoPageRoute是 Cupertino 組件庫提供的 iOS 風(fēng)格的路由切換組件,它實(shí)現(xiàn)的就是左右滑動切換。那么我們?nèi)绾蝸碜远x路由切換動畫呢?答案就是PageRouteBuilder。下面我們來看看如何使用PageRouteBuilder來自定義路由切換動畫。例如我們想以漸隱漸入動畫來實(shí)現(xiàn)路由過渡,實(shí)現(xiàn)代碼如下:

  1. Navigator.push(
  2. context,
  3. PageRouteBuilder(
  4. transitionDuration: Duration(milliseconds: 500), //動畫時間為500毫秒
  5. pageBuilder: (BuildContext context, Animation animation,
  6. Animation secondaryAnimation) {
  7. return new FadeTransition(
  8. //使用漸隱漸入過渡,
  9. opacity: animation,
  10. child: PageB(), //路由B
  11. );
  12. },
  13. ),
  14. );

我們可以看到pageBuilder 有一個animation參數(shù),這是 Flutter 路由管理器提供的,在路由切換時pageBuilder在每個動畫幀都會被回調(diào),因此我們可以通過animation對象來自定義過渡動畫。

無論是MaterialPageRoute、CupertinoPageRoute,還是PageRouteBuilder,它們都繼承自 PageRoute 類,而PageRouteBuilder其實(shí)只是PageRoute的一個包裝,我們可以直接繼承PageRoute類來實(shí)現(xiàn)自定義路由,上面的例子可以通過如下方式實(shí)現(xiàn):

  1. 定義一個路由類FadeRoute

  1. class FadeRoute extends PageRoute {
  2. FadeRoute({
  3. @required this.builder,
  4. this.transitionDuration = const Duration(milliseconds: 300),
  5. this.opaque = true,
  6. this.barrierDismissible = false,
  7. this.barrierColor,
  8. this.barrierLabel,
  9. this.maintainState = true,
  10. });
  11. final WidgetBuilder builder;
  12. @override
  13. final Duration transitionDuration;
  14. @override
  15. final bool opaque;
  16. @override
  17. final bool barrierDismissible;
  18. @override
  19. final Color barrierColor;
  20. @override
  21. final String barrierLabel;
  22. @override
  23. final bool maintainState;
  24. @override
  25. Widget buildPage(BuildContext context, Animation<double> animation,
  26. Animation<double> secondaryAnimation) => builder(context);
  27. @override
  28. Widget buildTransitions(BuildContext context, Animation<double> animation,
  29. Animation<double> secondaryAnimation, Widget child) {
  30. return FadeTransition(
  31. opacity: animation,
  32. child: builder(context),
  33. );
  34. }
  35. }

  1. 使用FadeRoute

  1. Navigator.push(context, FadeRoute(builder: (context) {
  2. return PageB();
  3. }));

雖然上面的兩種方法都可以實(shí)現(xiàn)自定義切換動畫,但實(shí)際使用時應(yīng)優(yōu)先考慮使用 PageRouteBuilder,這樣無需定義一個新的路由類,使用起來會比較方便。但是有些時候PageRouteBuilder是不能滿足需求的,例如在應(yīng)用過渡動畫時我們需要讀取當(dāng)前路由的一些屬性,這時就只能通過繼承PageRoute的方式了,舉個例子,假如我們只想在打開新路由時應(yīng)用動畫,而在返回時不使用動畫,那么我們在構(gòu)建過渡動畫時就必須判斷當(dāng)前路由isActive屬性是否為true,代碼如下:

  1. @override
  2. Widget buildTransitions(BuildContext context, Animation<double> animation,
  3. Animation<double> secondaryAnimation, Widget child) {
  4. //當(dāng)前路由被激活,是打開新路由
  5. if(isActive) {
  6. return FadeTransition(
  7. opacity: animation,
  8. child: builder(context),
  9. );
  10. }else{
  11. //是返回,則不應(yīng)用過渡動畫
  12. return Padding(padding: EdgeInsets.zero);
  13. }
  14. }

關(guān)于路由參數(shù)的詳細(xì)信息讀者可以自行查閱 API 文檔,比較簡單,不再贅述。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號