Hi, 我是魚板伯爵今天要教大家 Auto Router 這個套件,教學內容只會擷取片段程式碼,建議大家搭配完整程式碼來練習。
有時候App需要切換很多個頁面,或者太多頁面的路徑常常很難找出錯誤,我們可以使用Autorouter來幫助我們簡化程式碼,如果有哪個路徑不對,只需要檢查我們設定的參數是否有錯誤就可以了。
auto_route為我們這次主要的套件,而auto_route_generator與build_runner是為了可以生成我們路由的套件。
dependencies:
  flutter:
    sdk: flutter
  auto_route: ^2.3.0
dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:
  auto_route_generator: ^2.1.0
完成以下的的路由設定後,在終端機(Terminal)上執行flutter pub run build_runner watch --delete-conflicting-outputs指令就會生成出router.gr.dart的檔案。
initial:預設路徑page:頁面path:自訂路徑children:子路徑router.dart
import 'package:auto_route/auto_route.dart';
import 'package:day12/demo.dart';
import 'package:day12/transitions.dart';
// flutter pub run build_runner watch --delete-conflicting-outputs
@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
  ],
)
class $AppRouter {}
main.dart
import 'package:day12/demo.dart';
import 'package:day12/router.gr.dart';
import 'package:flutter/material.dart';
void main() {
  final AppRouter appRouter = AppRouter();
  runApp(
    MyApp(
      appRouter: appRouter,
    ),
  );
}
class MyApp extends StatelessWidget {
  final AppRouter _appRouter;
  MyApp({
    Key? key,
    required AppRouter appRouter,
  })  : _appRouter = appRouter,
        super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerDelegate: _appRouter.delegate(),
      routeInformationParser: _appRouter.defaultRouteParser(),
      builder: (context, router) => router!,
    );
  }
}
首先所有的場景都會在Stack裡,利用replace、navigate、push和pop,來控制所有頁面的進出。若後面有加上Named的元件則代表使用自己所定義的path來控制路由。
replace:覆蓋原本的頁面navigate:如果沒在stack就加入push:加入一個新的介面在stackpop:退出stackclass LoginScreen extends StatelessWidget {
  const LoginScreen({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("LoginScreen"),
      ),
      backgroundColor: Colors.indigo[50],
      body: Center(
        child: TextButton(
          child: Text("Sign in"),
          onPressed: () {
            // 轉場
            AutoRouter.of(context).replaceNamed("/home-screen");
          },
        ),
      ),
    );
  }
}

transitionsBuilder:轉場動畫設定durationInMilliseconds:轉場動畫時間@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
    CustomRoute(
      path: '/menu-screen',
      page: MenuScreen,
      transitionsBuilder: TransitionsBuilders.fadeIn,
      durationInMilliseconds: 1000,
    ),
  ],
)
class $AppRouter {}

我們可以用transitionsBuilder來寫自己的轉場動畫,至於如何控制就交給大家自己摸索了,以下就寫一個簡單的範例給大家參考。
@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
    CustomRoute(
      path: '/menu-screen',
      page: MenuScreen,
      transitionsBuilder: MyTransitions.slideBottomToTop,
      durationInMilliseconds: 1000,
    ),
  ],
)
class $AppRouter {}
class MyTransitions extends TransitionsBuilders {
  static const RouteTransitionsBuilder slideBottomToTop = _slideBottomToTop;
  static Widget _slideBottomToTop(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(0, 1),
        end: Offset.zero,
      ).animate(animation),
      child: child,
    );
  }
}

由於是Gif的緣故可能有點卡頓的感覺。