[Day12] Flutter - 场景路径与转换 ( Auto Router )

前言

Hi, 我是鱼板伯爵今天要教大家 Auto Router 这个套件,教学内容只会撷取片段程序码,建议大家搭配完整程序码来练习。

完整程序码

有时候App需要切换很多个页面,或者太多页面的路径常常很难找出错误,我们可以使用Autorouter来帮助我们简化程序码,如果有哪个路径不对,只需要检查我们设定的参数是否有错误就可以了。

安装套件

auto_route为我们这次主要的套件,而auto_route_generatorbuild_runner是为了可以生成我们路由的套件。

dependencies:
  flutter:
    sdk: flutter
  auto_route: ^2.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:
  auto_route_generator: ^2.1.0

AutoRouter 常用属性

完成以下的的路由设定後,在终端机(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里,利用replacenavigatepushpop,来控制所有页面的进出。若後面有加上Named的元件则代表使用自己所定义的path来控制路由。

  • replace:覆盖原本的页面
  • navigate:如果没在stack就加入
  • push:加入一个新的介面在stack
  • pop:退出stack
class 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");
          },
        ),
      ),
    );
  }
}

CustomRoute 使用其他的转场动画

  • 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,
    );
  }
}

Note:

由於是Gif的缘故可能有点卡顿的感觉。


<<:  Day 4 - TiDB架构说明

>>:  [13th][Day2] 变数

【後转前要多久】# Day13 CSS - Display: Flex (vs Float)

当没有任何CSS时, HTML预设显示区块元素(block)方式都是 往下一行一行(row)长 HT...

【第六天 - Flutter 多国语系】

前言 今日的程序码 => GITHUB 这边我想要介绍如何切换语言、设定 App 初始的语言,...

excel 函数求解

求解 excel函数问题 有A.B.C3个数 条件一.3个数范围4.5+—1 条件二.任两个相减不得...

Day28 - 铁人付外挂部署与发行(一)- 建立测试机

开发 WooCommerce 金流外挂能在本机测试的部分除了确保设定项有正确写入资料库外,剩下的就是...

Day-14:使用View Helper

Rails程序码整理(起步) 如何使用View Helper把这段逻辑藏起来: 使用View Hel...