[譯] 關於 Flutter 頁面路由過渡動畫,你所須要知道的一切

在使用 Flutter 的時候,咱們都知道從一個路由跳轉到另外一個這件事很是簡單。咱們只須要作 push 和 pop 的操做便可。前端

push 操做:android

Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),
  );
複製代碼

pop 操做:ios

Navigator.pop(context);
複製代碼

就這麼簡單。可是這樣作,路由跳轉就是無聊的頁面切換,徹底沒有動畫效果 😦git

當咱們在 Winkl 開始第一次應用動畫效果,咱們意識到,頁面跳轉的過渡效果可讓你的用戶交互界面變得很好看。若是你想要一個像 iOS 上那樣的滑動頁面切換,你能夠用 CupertinoPageRoute。只有這個,沒有其餘的了。github

Navigator.push(
    context, CupertinoPageRoute(builder: (context) => Screen2()))
複製代碼

可是,對於用戶自定義的過渡效果,Flutter 提供了不一樣的方案:動畫組件。下面咱們一塊兒來看看如何應用它。後端

咱們知道,Navigator.push 接受兩個參數 (BuildContext context, Route route)。咱們能夠使用一些過渡動畫來建立自定義的頁面路由跳轉。咱們先從一些簡單的例子開始,好比滑動過渡。bash

滑動過渡

首先,咱們要擴充類 PageRouteBuilder,而後定義 transitionsBuilder,它將返回滑動過渡組件。這個滑動過渡組件將使用類型 Animation 的位置信息,咱們將會使用 Tween 來給出動畫開始和結束的偏移量。ide

import 'package:flutter/material.dart';

class SlideRightRoute extends PageRouteBuilder {
  final Widget page;
  SlideRightRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              SlideTransition(
                position: Tween<Offset>(
                  begin: const Offset(-1, 0),
                  end: Offset.zero,
                ).animate(animation),
                child: child,
              ),
        );
}
複製代碼

咱們如今就能夠像這樣使用 SlideRightRoute ,代替了以前的 MaterialPageRoute學習

Navigator.push(context, SlideRightRoute(page: Screen2()))
複製代碼

代碼運行的效果是...區塊鏈

代碼很是簡單的對吧?你能夠經過修改偏移量 offset 來改變滑動過渡的方向。

縮放過渡

縮放過渡會經過改變組件的大小來完成動畫效果。你也能夠經過修改 CurvedAnimationcurves 來改變更畫。下面這個例子我使用的是 Curves.fastOutSlowIn。

import 'package:flutter/material.dart';

class ScaleRoute extends PageRouteBuilder {
  final Widget page;
  ScaleRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              ScaleTransition(
                scale: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.fastOutSlowIn,
                  ),
                ),
                child: child,
              ),
        );
}
複製代碼

代碼運行的效果是...

旋轉過渡

旋轉過渡會以轉動做爲組件的動畫。你也能夠爲你的 PageRouteBuilder 加入 transitionDuration

import 'package:flutter/material.dart';

class RotationRoute extends PageRouteBuilder {
  final Widget page;
  RotationRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionDuration: Duration(seconds: 1),
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              RotationTransition(
                turns: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.linear,
                  ),
                ),
                child: child,
              ),
        );
}
複製代碼

代碼運行的效果是...

大小過渡

import 'package:flutter/material.dart';

class SizeRoute extends PageRouteBuilder {
  final Widget page;
  SizeRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Align(
                child: SizeTransition(
                  sizeFactor: animation,
                  child: child,
                ),
              ),
        );
}
複製代碼

代碼運行的效果是...

漸變過渡

import 'package:flutter/material.dart';

class FadeRoute extends PageRouteBuilder {
  final Widget page;
  FadeRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              FadeTransition(
                opacity: animation,
                child: child,
              ),
        );
}
複製代碼

代碼運行的效果是...

棒棒噠!! 如今咱們學習過了全部基礎的過渡效果。


如今咱們來實踐一些更高級的。若是在進入頁面和離開頁面這兩個路由跳轉的時候都想要動畫該怎麼作呢?咱們能夠使用堆棧過渡動畫(stack transition animations),並應用於這兩個路由跳轉上。一個例子就是滑入新頁面,而後劃出舊頁面。這是我最喜歡的過渡動畫了 ❤️。咱們來看看代碼是如何實現的。

import 'package:flutter/material.dart';

class EnterExitRoute extends PageRouteBuilder {
  final Widget enterPage;
  final Widget exitPage;
  EnterExitRoute({this.exitPage, this.enterPage})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              enterPage,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Stack(
                children: <Widget>[
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(0.0, 0.0),
                      end: const Offset(-1.0, 0.0),
                    ).animate(animation),
                    child: exitPage,
                  ),
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(1.0, 0.0),
                      end: Offset.zero,
                    ).animate(animation),
                    child: enterPage,
                  )
                ],
              ),
        );
}
複製代碼

而後以下這樣來使用 EnterExitRoute:

Navigator.push(context,
    EnterExitRoute(exitPage: this, enterPage: Screen2()))
複製代碼

代碼運行的效果是...


咱們也能夠將多個過渡效果結合在一塊兒,建立出不少神奇的效果,好比同時應用縮放和旋轉。首先,建立 ScaleTransition,它的 child 屬性包括了 RotationTransition,而 RotationTransition 的 child 屬性則是要顯示動畫的頁面。

import 'package:flutter/material.dart';

class ScaleRotateRoute extends PageRouteBuilder {
  final Widget page;
  ScaleRotateRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionDuration: Duration(seconds: 1),
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              ScaleTransition(
                scale: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.fastOutSlowIn,
                  ),
                ),
                child: RotationTransition(
                  turns: Tween<double>(
                    begin: 0.0,
                    end: 1.0,
                  ).animate(
                    CurvedAnimation(
                      parent: animation,
                      curve: Curves.linear,
                    ),
                  ),
                  child: child,
                ),
              ),
        );
}
複製代碼

代碼運行的效果是...


棒極了!這些就是關於 Flutter 頁面路由過渡動畫,你所須要知道的一切。親自試着將不一樣的過渡效果結合起來,創造出一些很棒的動畫吧,而且別忘了和我分享你的成果。全部代碼的源碼可見:GitHub 倉庫


若是你喜歡本篇文章那就請點個贊吧,而且能夠在 TwitterGithubLinkedIn 聯繫我。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索