
今日的程式碼 => GitHub
大家應該都知道 Flutter 的跳頁都會分成 2 種方式
這邊我會簡單介紹一下這兩者的用法,想要分享一下,我習慣用的方法,和資料夾的架構。
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,到時候會再次帶入這個觀念。
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);
}
假設現在有個情境 A 畫面要跳到 B,在這邊我會寫成 A->B 的樣子。
沒有哪一種比較好,就是看習慣問題而已。It's up to you.
我自己是用 Named 的方式。(我覺得這樣比較好控制跳頁的動畫等等~~,我可以專門開一個頁面管理它)。
     return MaterialApp(
        // 告知我的路由器是哪個
        onGenerateRoute: MyRouter.generateRoute,
        // 告知 App 開啟後第一個畫面是什麼
        initialRoute: RouteName.aaa
    );
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
Animation 的 Builder,這邊可以客製化它。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);
}