Flutter app页面路由以及路由拦截的实现

为什么要使用路由

在之前我们的代码中,页面跳转使用的代码如下所示:

 Navigator.of(context).push(
  MaterialPageRoute(builder: (context) => LoginPage()),
);

在开发过程中,随着页面的增加,如果继续使用这种方式会有如下缺陷:

  • 代码耦合严重:涉及到页面跳转的地方就需要插入页面的构造函数,意味着需要知道其他页面的构建方式。
  • 不易维护:一旦某个页面发生了变化,需要将涉及到该页面的跳转全部改变。
  • 权限控制不方便:假设某些页面需要授权后才可以访问,需要在各个地方插入权限判断。

Flutter路由介绍

首先说一下,本篇的路由介绍是 Flutter 1.0的实现方式,Flutter 2.0对路由做了很大的改动,使用了声明式方式重构了路由,使用起来会更为复杂。在 Flutter 的 MaterialApp提供了路由配置参数,当使用路由配置后,MaterialApp 的构造形式如下所示:

return MaterialApp(
  //其他参数...
  navigatorKey: //全局导航状态Key,
  onGenerateRoute: //路由改变响应方法,
  initialRoute: //初始化路由路径,
);
  • navigatorKey是一个GlobalKey<NavigatorState>对象,用于全局存储导航的状态。
  • onGenerateRoute为一个路由拦截器,当路由发生改变时,该方法会被调用,从而可以根据路由参数返回不同的页面,或者进行路由拦截。
  • initialRoute为初始化路由路径,一般为启动页或首页的路径。

页面结构与逻辑

为了演示路由的使用,我们使用了四个页面:

  • AppHomePage :首页,与之前的章节的页面框架一样,路由路径为“/”;
  • Splash:启动页,只有一个图片,实际使用过程可以用于加载引导页,广告或其他用途。页面停留2秒后切换到首页。
  • LoginPage:登录页,用于演示点击登录按钮通过路由切换到登录页。
  • NotFound:即404页面,当路由表中没有匹配的路径时,跳转到404页面。

这里的路由跳转分为了两种,一是从启动页跳转到首页,这种跳转不可返回的;二是正常的调整,可以点击返回按钮返回到上一级。在 Flutter 中提供不同的方法应对这两种情况。

实现关键代码

首先是路由表和路由拦截响应的实现,在 routers文件夹新建 router_table.dart 文件,代码如下:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../app.dart';
import '../login.dart';
import '../not_found.dart';
import '../splash.dart';

class RouterTable {
  static String splashPath = 'splash';
  static String loginPath = 'login';
  static String homePath = '/';
  static String notFoundPath = '404';

  static Map<String, WidgetBuilder> routeTables = {
    //404页面
    notFoundPath: (context) => NotFound(),
    //启动页
    splashPath: (context) => Splash(),
    //登录
    loginPath: (context) => LoginPage(),
    //首页
    homePath: (context) => AppHomePage(),
  };

  ///路由拦截
  static Route onGenerateRoute<T extends Object>(RouteSettings settings) {
    return CupertinoPageRoute<T>(
      settings: settings,
      builder: (context) {
        String name = settings.name;
        if (routeTables[name] == null) {
          name = notFoundPath;
        }

        Widget widget = routeTables[name](context);

        return widget;
      },
    );
  }
}

这里全部使用了静态属性和静态方法,是为了可以直接从过类名访问属性和方法,而无需反复构建对象。这样,路由访问的时候也可以通过类名的静态属性直接访问,可以避免拼写错误。有了这个类了后,App 的所有页面都可以通过这个类集中管理,从而避免多处维护了。

这里关键的是onGenerateRoute方法,该方法接收了一个 RouteSettings 对象,该对象会有个 name 属性包含路由路径名称,同时还有个 arguments 用于携带路由参数。可以通过这个属性来与路由表的页面进行匹配。若匹配到则返回相应的页面;若没有匹配到,则路由到404页面。同时,若需要做权限控制,也可以在这里拦截,比如定位到403页面或直接提醒无访问权限。

接下来就是改造 main.dart 文件,在构建 MaterialApp 时使用对应的理由配置:

import 'package:flutter/material.dart';
import 'routers/router_table.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final GlobalKey navigationKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigationKey,
      onGenerateRoute: RouterTable.onGenerateRoute,
      initialRoute: RouterTable.splashPath,
    );
  }
}

这里会发现在 main.dart中我们无需再通过 import引入相关的页面 了,而是直接配置路由的配置属性即可。

页面路由跳转

页面路由跳转更为简便,在 Flutter 中的 NavigatorState 中分别提供了 pushNamed 方法和pushReplacementNamed 方法,前者会在导航栏有返回按钮,后者是使用路由后的页面直接替换当前页面,适用于启动页的调整。 在启动页中未来停留几秒,使用了一个定时器,在2秒后再进行跳转,实际可以用于做一些预加载资源的提示或者广告展示。

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  if (!_initialized) {
    _initialized = true;
    Timer(const Duration(milliseconds: 2000), () {
      Navigator.of(context).pushReplacementNamed(RouterTable.homePath);
    });
  }
}

普通页面的跳转直接使用 pushNamed 即可,若要返回上一级,则使用 pop 方法。push 和 pop方法均可以携带参数,下一篇我们再来介绍如何处理路由参数。这里我们特意加了一个错误的路由演示404跳转:

body: Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      ButtonUtil.primaryTextButton('登录', () {
        Navigator.of(context).pushNamed(RouterTable.loginPath);
      }, context),
      SizedBox(
        height: 10,
      ),
      ButtonUtil.primaryTextButton('404', () {
        Navigator.of(context).pushNamed('errorRoute');
      }, context),
    ],
  ),
),

最终运行效果如下图所示。

以上就是Flutter app页面路由以及路由拦截的实现的详细内容,更多关于Flutter 路由的资料请关注我们其它相关文章!

(0)

相关推荐

  • Flutter上线项目实战记录之路由篇

    1. 应用场景 开发中经常遇到 路由跳转时拿不到context怎么办,eg: token失效/异地登录跳转登录页面. 获取不到当前路由名称怎么办,eg: 点击push推送跳转指定路由,如果已经在当前页面就replace,如果不在就push. 注册监听路由跳转,做一些想做的事情 ,eg:不同路由,显示不同状态栏颜色. 等等... 2. 解决方案 解决思路: MaterialApp 的routes属性赋值路由数组,navigatorObservers属性赋值路由监听对象NavigatorManage

  • Flutter路由的跳转、动画和传参详解(最简单)

    路由 做Android/iOS原生开发的时候,要打开一个新的页面,你得知道你的目标页面对象,然后初始化一个Intent或者ViewController,再通过startActivity或者pushViewController来推出一个新的页面,不能跟web一样,直接丢一个链接地址就跳转到新的页面.当然,可以自己去加一个中间层来实现这些功能. Flutter里面是原生支持路由的.Flutter的framework提供了路由跳转的实现.我们可以直接使用这些功能. Flutter路由介绍 Flutte

  • 详解Flutter的路由导航

    Flutter 的路由导航 路由管理或导航管理:从一个页面平滑地过渡到另一个页面,我们需要有一个统一的机制来管理页面之间的跳转.在原生的Android 开发,是通过startActivity或startActivityForResult 来完成页面的跳转的,在Flutter 中如何实现呢? 在 Flutter 中,页面之间的跳转是通过 Route 和 Navigator 来管理的: Route 是页面的抽象,主要负责创建对应的界面,接收参数,响应 Navigator 打开和关闭: 而 Navig

  • Flutter开发之路由与导航的实现

    如果说构成视图元素的基本单位是组件,那么构成应用程序的基本单位就是页面.对于拥有多个页面的应用程序而言,如何从一个页面平滑地过渡到另一个页面,是技术框架需要考虑的问题. 在前端开发中,可以使用路由框架来统一管理页面及它们之间的跳转.在Android中路由指的是一个Activity,在iOS中指的是一个ViewController,可以通过startActivity或pushViewController来打开一个新的路由.在Flutter中,路由的管理和导航借鉴了前端和客户端的设计思路,需要使用R

  • Flutter利用注解生成可自定义的路由的实现

    route_generator是什么 这是一个简单的 Flutter 路由生成库,只需要少量的代码,然后利用注解配合源代码生成,自动生成路由表,省去手工管理路由代码的烦恼. 特性 自定义路由名称 自定义路由动画 自定义路由参数 自定义路由逻辑 依赖 dependencies: # Your other regular dependencies here route_annotation: ^0.1.0 dev_dependencies: # Your other dev_dependencies

  • flutter 路由跳转的实现示例

    路由 做Android/iOS原生开发的时候,要打开一个新的页面,你得知道你的目标页面对象,然后初始化一个Intent或者ViewController,再通过startActivity或者pushViewController来推出一个新的页面,不能跟web一样,直接丢一个链接地址就跳转到新的页面.当然,可以自己去加一个中间层来实现这些功能. Flutter里面是原生支持路由的.Flutter的framework提供了路由跳转的实现.我们可以直接使用这些功能. Flutter路由介绍 Flutte

  • flutter 自定义websocket路由的实现

    在 flutter websocket 中 服务端推送数据给客户端后 很多人的处理居然都是 if / switch; 感觉这样的写法不咋好! 自己想的一个办法: 在 lib 目录下新建一个 socket 目录 里面创建两个文件main.dart和router.dart; main.dart : 主要控制websocket的连接 断开 和收到消息的处理; router.dart 则为websocket 服务端返回的消息做路由处理; router.dart import 'package:lee/l

  • Flutter路由框架Fluro使用简介

    在Flutter应用开发过程中,除了使用Flutter官方提供的路由外,还可以使用一些第三方路由框架来实现页面管理和导航,如Fluro.Frouter等. Fluro作为一款优秀的Flutter企业级路由框架,Fluro的使用比官方提供的路由框架要复杂一些,但是却非常适合中大型项目.因为它具有层次分明.条理化.方便扩展和便于整体管理路由等优点. 使用Fluro之前需要先在pubspec.yaml文件中添加Fluro依赖,如下所示. dependencies: fluro: "^1.5.1&quo

  • Flutter 局部路由实现详解

    Flutter是借鉴React的开发思想实现的,在子组件的插槽上,React有this.props.children,Vue有<slot></slot>. 当然Flutter也有类似的Widget,那就是Navigator,不过是以router的形式实现(像<router-view></router-view>???). Navigator的使用无非3个属性 initialRoute: 初始路由 onGenerateRoute: 匹配路由 onUnknown

  • Flutter app页面路由以及路由拦截的实现

    为什么要使用路由 在之前我们的代码中,页面跳转使用的代码如下所示: Navigator.of(context).push( MaterialPageRoute(builder: (context) => LoginPage()), ); 在开发过程中,随着页面的增加,如果继续使用这种方式会有如下缺陷: 代码耦合严重:涉及到页面跳转的地方就需要插入页面的构造函数,意味着需要知道其他页面的构建方式. 不易维护:一旦某个页面发生了变化,需要将涉及到该页面的跳转全部改变. 权限控制不方便:假设某些页面需

  • Flutter实现页面路由及404路由拦截

    为什么要使用路由 在之前我们的代码中,页面跳转使用的代码如下所示: Navigator.of(context).push( MaterialPageRoute(builder: (context) => LoginPage()), ); 在开发过程中,随着页面的增加,如果继续使用这种方式会有如下缺陷: 代码耦合严重:涉及到页面跳转的地方就需要插入页面的构造函数,意味着需要知道其他页面的构建方式. 不易维护:一旦某个页面发生了变化,需要将涉及到该页面的跳转全部改变. 权限控制不方便:假设某些页面需

  • vue路由实现登录拦截

    一.概述 在项目开发中每一次路由的切换或者页面的刷新都需要判断用户是否已经登录,前端可以判断,后端也会进行判断的,我们前端最好也进行判断. vue-router提供了导航钩子:全局前置导航钩子 beforeEach和全局后置导航钩子 afterEach,他们会在路由即将改变前和改变后进行触发.所以判断用户是否登录需要在beforeEach导航钩子中进行判断. 导航钩子有3个参数: 1.to:即将要进入的目标路由对象: 2.from:当前导航即将要离开的路由对象: 3.next :调用该方法后,才

  • 微信小程序学习笔记之页面配置与路由方式

    最近在学习回顾小程序的开发,将一些学习结果做个笔记.参考微信小程序官方文档:developers.weixin.qq.com/miniprogram- 一.小程序配置 1.全局配置 小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. // 示例 { "pages": [ "pages/index/index", "pages/logs/index" ], &q

  • vue3缓存页面keep-alive及路由统一处理详解

    目录 一.前言 二.使用 1.vue2和vue3的不同 2.页面某些数据不需要缓存 3.动态设置keepAlive属性 4.使用include,exclude配置需要缓存的组件 5.部分页面过来需要缓存,部分页面过来需要刷新 6.缓存只在一级路由生效 总结 一.前言 当使用路由跳转到其他页面的时候,要求缓存当前页面,比如列表页面跳转到详情页面,需要缓存列表内容,并且保存滚动条位置,也有时候需要缓存的页面里面有部分内容不缓存,总之各种情况,下面就列举其中一些例子 vue2和vue3的使用方式是不一

  • Flutter定义tabbar底部导航路由跳转的方法

    本文实例为大家分享了Flutter定义tabbar底部导航路由跳转的具体代码,供大家参考,具体内容如下 效果展示 整体实现的目录结构 第一步 把三个页面放到tabs里 Category.dart || Home.dart || Setting.dart 在这里我只展示 Home.dart 另外两个页面相同 import 'package:flutter/material.dart'; class HomePage extends StatefulWidget {   HomePage({Key

  • vue多页面项目中路由使用history模式的方法

    前言 之前写了一个vue项目中需要添加一个打印的页面,需要使用多页面的模式进行开发,vue-cli3出初始化的项目配置多页面还是很容易的,但是发现print.html没有办法配置history模式的路由,一旦使用history模式的路由.写了一个简单的demo在网上寻求帮助没有能解决问题,后来没有办法只能使用hash模式完整项目了. 如何解决 有一天看webpack文档的时候,突然看到了historyApiFallback配置项,一瞬间感觉找到方法了.下班后回家就下载下之前的项目折腾了. 之前的

  • vue实现app页面切换动画效果实例

    因为需要实现类似APP页面切换的动画效果,百度google搜索比较少资料,所以自己写文档,希望对您有用 在router/index.js import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) Router.prototype.goBack = function () { this.isBack = true window.history.go(-1) } const router = new Router({

  • Vue的路由及路由钩子函数的实现

    什么是路由 什么是路由?网络原理中,路由指的是根据上一接口的数据包中的IP地址,查询路由表转发到另一个接口,它决定的是一个端到端的网络路径. web中,路由的概念也是类似,根据URL来将请求分配到指定的一个'端'.(即根据网址找到能处理这个URL的程序或模块) 使用vue.js构建项目,vue.js本身就可以通过组合组件来组成应用程序:当引入vue-router后,我们需要处理的是将组件(components)映射到路由(routes),然后在需要的地方进行使用渲染. 其所包含的功能有: 嵌套的

  • vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作

    最近开发vue项目,遇到的一些问题,这里整合一下,看到一些博客已经有写相关知识,然后自己再次记录一下. 这是关于vue路由相关比较常见的问题,以后遇到相关路由的问题,会不断更新这篇博客. 需求1:从填写表单A页面跳转到B页面,然后再从B页面返回到A页面,实现A页面的所填的数据保留 一.设置路由缓存: 1.App.vue中加入<keep-alive> 具体代码如下: <template> <div id="app"> <!--<img sr

随机推荐