Flutter 新闻客户端 - 08 路由管理 auto_route

Flutter 新闻客户端 - 08 路由管理 auto_route_第1张图片

B站视频

https://www.bilibili.com/vide...

本节目标

  • 安装插件
  • 路由定义
  • 自动生成路由控制类
  • 转场动画
  • 登录检查中间件
  • 带参数传递
  • 获取返回值

正文

一些优秀的路由插件

  • fluro

    前端的使用体验

    router.navigateTo(context, "/users/1234", transition: TransitionType.fadeIn);

  • flutter_modular

    功能强大的路由管理:中间件、懒加载、状态管理、动态路由、分组路由、动画、返回值、命名路由

  • auto_route

    设计精简、低耦合其它功能

    功能:中间件、自动生成路由代码、动态路由、动画、返回值、命名路由

安装插件

  • 官网

https://pub.flutter-io.cn/pac...

  • pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  # 路由管理
  auto_route: ^0.4.4

dev_dependencies:
  flutter_test:
    sdk: flutter

  # 路由生成
  auto_route_generator: ^0.4.4
  build_runner:

路由定义

  • lib/common/router/router.dart
@MaterialAutoRouter()
class $AppRouter {
  @initial
  IndexPage indexPageRoute;

  WelcomePage welcomePageRoute;

  SignInPage signInPageRoute;

  SignUpPage signUpPageRoute;

  ApplicationPage applicationPageRoute;

  DetailsPage detailsPageRoute;
}
注意 $ 符号

自动生成路由控制类

  • 执行命令
flutter packages pub run build_runner build
  • 自动生成 lib/common/router/router.gr.dart
// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// AutoRouteGenerator
// **************************************************************************

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter_ducafecat_news/pages/index/index.dart';
import 'package:flutter_ducafecat_news/pages/welcome/welcome.dart';
import 'package:flutter_ducafecat_news/pages/sign_in/sign_in.dart';
import 'package:flutter_ducafecat_news/pages/sign_up/sign_up.dart';
import 'package:flutter_ducafecat_news/pages/application/application.dart';
import 'package:flutter_ducafecat_news/common/router/auth_grard.dart';
import 'package:flutter_ducafecat_news/pages/details/details.dart';

abstract class Routes {
  static const indexPageRoute = '/';
  static const welcomePageRoute = '/welcome-page-route';
  static const signInPageRoute = '/sign-in-page-route';
  static const signUpPageRoute = '/sign-up-page-route';
  static const applicationPageRoute = '/application-page-route';
  static const detailsPageRoute = '/details-page-route';
}

class AppRouter extends RouterBase {
  @override
  Map> get guardedRoutes => {
        Routes.applicationPageRoute: [AuthGuard],
        Routes.detailsPageRoute: [AuthGuard],
      };

  //This will probably be removed in future versions
  //you should call ExtendedNavigator.ofRouter() directly
  static ExtendedNavigatorState get navigator =>
      ExtendedNavigator.ofRouter();

  @override
  Route onGenerateRoute(RouteSettings settings) {
    final args = settings.arguments;
    switch (settings.name) {
      case Routes.indexPageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs = args as IndexPageArguments ?? IndexPageArguments();
        return MaterialPageRoute(
          builder: (_) => IndexPage(key: typedArgs.key),
          settings: settings,
        );
      case Routes.welcomePageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs =
            args as WelcomePageArguments ?? WelcomePageArguments();
        return MaterialPageRoute(
          builder: (_) => WelcomePage(key: typedArgs.key),
          settings: settings,
        );
      case Routes.signInPageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs = args as SignInPageArguments ?? SignInPageArguments();
        return MaterialPageRoute(
          builder: (_) => SignInPage(key: typedArgs.key),
          settings: settings,
        );
      case Routes.signUpPageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs = args as SignUpPageArguments ?? SignUpPageArguments();
        return MaterialPageRoute(
          builder: (_) => SignUpPage(key: typedArgs.key),
          settings: settings,
        );
      case Routes.applicationPageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs =
            args as ApplicationPageArguments ?? ApplicationPageArguments();
        return MaterialPageRoute(
          builder: (_) => ApplicationPage(key: typedArgs.key),
          settings: settings,
        );
      case Routes.detailsPageRoute:
        if (hasInvalidArgs(args)) {
          return misTypedArgsRoute(args);
        }
        final typedArgs =
            args as DetailsPageArguments ?? DetailsPageArguments();
        return MaterialPageRoute(
          builder: (_) => DetailsPage(key: typedArgs.key),
          settings: settings,
        );
      default:
        return unknownRoutePage(settings.name);
    }
  }
}

//**************************************************************************
// Arguments holder classes
//***************************************************************************

//IndexPage arguments holder class
class IndexPageArguments {
  final Key key;
  IndexPageArguments({this.key});
}

//WelcomePage arguments holder class
class WelcomePageArguments {
  final Key key;
  WelcomePageArguments({this.key});
}

//SignInPage arguments holder class
class SignInPageArguments {
  final Key key;
  SignInPageArguments({this.key});
}

//SignUpPage arguments holder class
class SignUpPageArguments {
  final Key key;
  SignUpPageArguments({this.key});
}

//ApplicationPage arguments holder class
class ApplicationPageArguments {
  final Key key;
  ApplicationPageArguments({this.key});
}

//DetailsPage arguments holder class
class DetailsPageArguments {
  final Key key;
  DetailsPageArguments({this.key});
}

路由跳转

  • 方式 1:带 context 方式
ExtendedNavigator.of(context).pushNamed(Routes.signUpPageRoute);
  • 方式 2:不带 context 方式
ExtendedNavigator.ofRouter().pushNamed(Routes.signUpPageRoute);
  • 方式 3:如果你只有一个导航
ExtenedNavigator.rootNavigator.pushNamed(Routes.signUpPageRoute);

转场动画

  • lib/common/router/router.dart
Widget zoomInTransition(BuildContext context, Animation animation,
    Animation secondaryAnimation, Widget child) {
  // you get an animation object and a widget
  // make your own transition
  return ScaleTransition(scale: animation, child: child);
}

@MaterialAutoRouter()
class $AppRouter {
  ...

  @CustomRoute(transitionsBuilder: zoomInTransition)
  ApplicationPage applicationPageRoute;
}
  • 重新生成
flutter packages pub run build_runner build

登录检查中间件

  • 创建 lib/common/router/auth_grard.dart
import 'package:auto_route/auto_route.dart';
import 'package:flutter_ducafecat_news/common/router/router.gr.dart';
import 'package:flutter_ducafecat_news/common/utils/utils.dart';

class AuthGuard extends RouteGuard {
  @override
  Future canNavigate(ExtendedNavigatorState navigator, String routeName,
      Object arguments) async {
    var isAuth = await isAuthenticated();
    if (isAuth == false) {
      ExtendedNavigator.rootNavigator.pushNamed(Routes.signInPageRoute);
    }

    return isAuth;
  }
}
  • 注册 lib/main.dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ducafecat.tech',
      debugShowCheckedModeBanner: false,
      builder: ExtendedNavigator(
        initialRoute: Routes.indexPageRoute,
        router: AppRouter(),
        guards: [AuthGuard()],
      ),
    );
  }
}
  • 定义 lib/common/router/router.dart
@MaterialAutoRouter()
class $AppRouter {
  ...

  @GuardedBy([AuthGuard])
  @CustomRoute(transitionsBuilder: zoomInTransition)
  ApplicationPage applicationPageRoute;
}
  • 重新生成
flutter packages pub run build_runner build

参数传递

  • 设定初始参数 lib/pages/details/details.dart
class DetailsPage extends StatefulWidget {
  final String cid;
  DetailsPage({Key key, this.cid}) : super(key: key);
  • 定义 lib/common/router/router.dart
@MaterialAutoRouter(generateNavigationHelperExtension: true)
class $AppRouter {
  ...
  • 重新生成
flutter packages pub run build_runner build
  • lib/common/router/router.gr.dart
//DetailsPage arguments holder class
class DetailsPageArguments {
  final Key key;
  final String cid;
  DetailsPageArguments({this.key, this.cid});
}
  • 导航参数
ExtendedNavigator.rootNavigator.pushDetailsPageRoute(cid: '123');
  • 获取返回值
    ExtendedNavigator.rootNavigator
        .pushNamed(Routes.signUpPageRoute)
        .then((onValue) {
      print(onValue);
    });

资源

视频

蓝湖设计稿(加微信给授权 ducafecat)

https://lanhuapp.com/url/lYuz1
密码: gSKl

蓝湖现在收费了,所以查看标记还请自己上传 xd 设计稿
商业设计稿文件不好直接分享, 可以加微信联系 ducafecat

YAPI 接口管理

http://yapi.demo.qunar.com/

代码

https://github.com/ducafecat/...

参考

https://pub.flutter-io.cn/pac...

VSCode 插件

你可能感兴趣的:(前端,flutter)