iT邦幫忙

2021 iThome 鐵人賽

DAY 3
1
Mobile Development

Flutter - 複製貼上到開發套件之旅系列 第 3

【第三天 - Flutter Route 規劃分享】


今日的程式碼 => GitHub

前言

大家應該都知道 Flutter 的跳頁都會分成 2 種方式

這邊我會簡單介紹一下這兩者的用法,想要分享一下,我習慣用的方法,和資料夾的架構。

MaterialPageRoute、Named

  1. MaterialPageRoute
    他有兩種寫法,兩種寫法都可以
Navigator.push(context, MaterialPageRoute(builder: (context)=> new Page1())),
Navigator.of(context, rootNavigator: false).push(MaterialPageRoute(builder: (context) => new Page1())),
  • 第二種寫法的 rootNavigator 非必填,預設為 false,代表他會去找距離你最近節點的 Navigator。如果 rootNavigator = true,他則會去找 App 一打開,第一個碰到的 Navigator。當作換頁的根據,也就是 MaterialApp 裡面的路由控制器。

如果這邊沒有聽懂的話,沒關係,之後會講 BottomNavigationBar,到時候會再次帶入這個觀念。

  1. Named
    必須設定路由
new MaterialApp(
  home: new Screen1(),
  routes: <String, WidgetBuilder> {
    'page1': (BuildContext context) => new Page1(),
    'page2' : (BuildContext context) => new Page2(),
  },
)
 Navigator.pushNamed(context, 'page2'),
Navigator.of(context,rootNavigator: false).pushNamed('page2'),

帶參數到下一個畫面

Navigator.pushNamed(context, RouteName.bbb, arguments: '注意,這邊只能傳一個參數,如果想要傳多個參數,請自己寫個物件包起來'),
@override
Widget build(BuildContext context) {
 final String string =ModalRoute.of(context)!.settings.arguments as String;
 return Text(string);
}
  1. 通用的觀念
  • 觀念:每一次跳頁就是堆積木一樣。

假設現在有個情境 A 畫面要跳到 B,在這邊我會寫成 A->B 的樣子。

  • push :A->B,積木由上到下,從 A 變成 B,A
  • pop :A->B,積木由上到下,從 A,B 變成 B
  • pushReplacement:A->B,蓋上去取代,積木由上到下,從 A 變成 B
  • popAndPushNamed:A->B,先移開最上層的在蓋上去,積木由上到下,從 A,C 變成 C 再變成 B,C
  • pushAndRemoveUntil::A->B,先蓋上去然後把底下的全部移開,積木由上到下,從 A,C 變成 B,A,C 再變成 B
  • 當然不只這些,剩下的可以去 官網

哪一種比較好?

沒有哪一種比較好,就是看習慣問題而已。It's up to you.

我自己是用 Named 的方式。(我覺得這樣比較好控制跳頁的動畫等等~~,我可以專門開一個頁面管理它)。

資料夾架構 + 如何管理 Route

  1. MyApp
     return MaterialApp(
        // 告知我的路由器是哪個
        onGenerateRoute: MyRouter.generateRoute,
        // 告知 App 開啟後第一個畫面是什麼
        initialRoute: RouteName.aaa
    );
  1. MyRouter
    這邊是我的路由控制器,控制要跳轉的畫面是哪個元件,使用什麼動畫跳轉。
    RouteName 是一個字串。
    MyRoute 會對應到畫面。
class RouteName {
  static const String aaa = 'aaa';
  static const String bbb = 'bbb';
}

class MyRouter {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case RouteName.aaa:
        return NoAnimRouteBuilder(new AAA());
      case RouteName.bbb:
        return NoAnimRouteBuilder(new BBB());
      default:
        return CupertinoPageRoute(
            builder: (_) => Scaffold(
                  body: Center(
                    child: Text('No route defined for ${settings.name}'),
                  ),
                ));
    }
  }
}

例:

Navigator.pushNamed(context, RouteName.aaa),

那這樣的話 MyRouter 的 settings.name 就會是 RouteName.aaa

  1. NoAnimRouteBuilder
    這是我用來控制 AnimationBuilder,這邊可以客製化它。

transitionsBuilder 的官方文件

class NoAnimRouteBuilder extends PageRouteBuilder {
  final Widget page;

  NoAnimRouteBuilder(this.page)
      : super(
      opaque: false,
      pageBuilder: (context, animation, secondaryAnimation) => page,
      transitionDuration: Duration(milliseconds: 0),
      transitionsBuilder:
          (context, animation, secondaryAnimation, child) => child);
}

上一篇
【第二天 - Flutter 繼承+建構子+CallBack 基本概念】
下一篇
【第四天 - Flutter BottomNavigationBar(上)Animation】
系列文
Flutter - 複製貼上到開發套件之旅30

1 則留言

0
SKYDOG
iT邦新手 5 級 ‧ 2021-09-17 20:51:01

/images/emoticon/emoticon07.gif

WenYeh iT邦新手 4 級 ‧ 2021-09-17 23:12:35 檢舉

/images/emoticon/emoticon39.gif

我要留言

立即登入留言