Flutter路由管理三方Fluro使用(一)

引言

对于Flutter路由的使用,从入门到深入一般有以下几个阶段:

  1. 初步了解到Flutter中是用路由(Route)表示页面(Page)。使用基本的MaterialPageRoute方式进行页面操作。
  2. 学会使用Navigator来完成路由操作。
  3. 学会使用命名路(Named Route)由来完成路由的管理与操作。
    以上三个阶段属于官方的基本知识。
  4. 使用三方Fluro完成路由的管理与操作。
  5. 使用注解方式完成路由的管理与操作。(闲鱼有三方)

本文在已经完成前三个阶段的状态下,阐述Fluro的使用。

首先假设我们的App组织架构如下

- login模块
- home模块
- buy模块
我们需要高效的管理现有页面路由,并兼顾后续页面扩展。

先来看Fluro的基本使用,进而分析为了完成我们的目标需要做哪些额外的工作

新建一个Flutter工程

在pubspec.yaml文件中添加Fluro三方

dependencies:
  flutter:
    sdk: flutter
  # 路由管理三方Fluro
  # https://github.com/theyakka/fluro
  fluro: ^1.6.3

.yaml文件对齐有严格要求
建议每个添加的三方库都附上简要说明和网址

修改基本代码

修改Home页面布局为中间一个按钮
添加一个Buy页面,布局也是中间一个按钮
源码lib1

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FlatButton(
          onPressed: () => print('进行跳转操作'),
          child: Text('点我 跳转到buy页面'),
        ),
      ),
    );
  }
}
根据作者的说明我们先初始化Router
final router = Router();

接下来我们浏览一下Router的源码,大致浏览都提供了哪些方法。
...假装看懂了,还是看作者说明吧。作者说明对新手也不怎么友好。。
好像有一行很短的样子,先看这一行。

You can also manually push to a route yourself. To do so:
router.navigateTo(context, "/users/1234", transition: TransitionType.fadeIn);

翻看一下源代码

///
Future navigateTo(BuildContext context, String path,
      {bool replace = false,
      bool clearStack = false,
      TransitionType transition,
      Duration transitionDuration = const Duration(milliseconds: 250),
      RouteTransitionsBuilder transitionBuilder}) {
     ....
     return future;
  }

作者留了个///给我们,忧伤
navigateTo方法接受一些参数,返回了一个future.
让我们看看future是个什么

if (route != null) {
        if (clearStack) {
          future =
              Navigator.pushAndRemoveUntil(context, route, (check) => false);
        } else {
          future = replace
              ? Navigator.pushReplacement(context, route)
              : Navigator.push(context, route);
        }
        ...
      }

默认的clearStack是false,replace是false,那么
future = Navigator.push(context, route);
这就是非常基础的Navigator用法了。
context是直接传入的参数,那么route是如何得到呢。

RouteMatch routeMatch = matchRoute(context, path,
        transitionType: transition,
        transitionsBuilder: transitionBuilder,
        transitionDuration: transitionDuration);
    Route<dynamic> route = routeMatch.route;

可以看到通过传入path等参数,通过使用matchRoute方法,我们获得到了route。暂时不用关心该方法的内部,大概的也能猜到path就是我们使用命名路由,注册路由表时的路由名。此时我们还没有使用命名路由注册路由表。
让我们直接使用作者给我们的说明代码

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

看看报错信息

flutter: No registered route was found to handle '/users/1234'.
flutter: 进行跳转操作
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: 
No registered route was found to handle '/users/1234'
null

提示我们路由没有注册。这个提示是fluro给出的。
是否就是使用命名路由时的注册路由表呢?我们添加一下代码

routes: {
        '/users/1234': (context) => BuyPage(),
      },

错误依然存在。那么让我们来看看fluro说的registered在哪里执行。
查看fluro的源码

/// The tree structure that stores the defined routes
  final RouteTree _routeTree = RouteTree();
    ...
  /// Creates a [PageRoute] definition for the passed [RouteHandler].
 /// You can optionally provide a default transition type.
  void define(String routePath,
      {@required Handler handler, TransitionType transitionType}) {
    _routeTree.addRoute(
      AppRoute(routePath, handler, transitionType: transitionType),
    );
  }

可以看到作者的解释
RouteTree 用来存储已经定义的路由
difine方法创建PageRoute
那么我们需要调用define方法来定义(registered)路由。

Widget build(BuildContext context) {
    ...
    router.define('/users/1234', handler: XXX);
    ...
}

那么这个handler是什么呢?查看一下源码

class Handler {
  Handler({this.type = HandlerType.route, this.handlerFunc});
  final HandlerType type;
  final HandlerFunc handlerFunc;
}
...
typedef Widget HandlerFunc(
    BuildContext context, Map<String, List<String>> parameters);

Handler是构造成HandlerType.route类型的类,需要传入this.handlerFunc参数
HandlerFunc是一个Widget,是BuildContext context, Map<String, List<String>> parameters的typedef定义。因此,我们要传送一个BuildContext context, Map<String, List<String>> parametersHandler当参数。

让我们构造一个buyPageHandler,参考作者的代码,返回值是一个路由Wiget(BuyPage())

var buyPageHandler = Handler(
        handlerFunc: (BuildContext context, Map<String, dynamic> params) {
      return BuyPage();
    });

此时,修改路由定义代码

router.define('/users/1234', handler: buyPageHandler);

运行程序 查看代码
可以看到,点击HomePage的按钮已经正常能够跳转到BuyPage。

让我们回一下为了,实现跳转Fluro都做了哪些事情。
  1. 初始化了一个router
  2. 定义了一个buyPageHandler。可以传入params,返回一个route类型的Widget.
  3. 定义了一个router,需要传入name和handler两个参数
  4. 使用navigateTo,传入name,进行页面跳转。
    至此Fluro的最基本用法已经说明完毕。让我们回到最初的那个问题

我们的App组织架构如下

- login模块
- home模块
- buy模块
我们需要高效的管理现有页面路由,并兼顾后续页面扩展。

如果我们想在BuyPage跳转到HomePage页面,那么刚才的4个步骤我们需要一个不落的重新一遍。重新就意味着可以抽离相同的代码。比如抽离route的初始化。

如果我们想在LoginPage页面也跳转到HomePage页面,那么步骤 2 3也可以抽离出来单独定义,从而进行复用。我们可以清晰的看到步骤 2 3是跳转目标页面的定义,而与到底从哪个页面跳转来无关。

如何进行抽离呢?作者的说明里有这么两句话。。

It may be convenient for you to store the router globally/statically so that you can access the router in other areas in your application.

You can use the Router with the MaterialApp.onGenerateRoute parameter via the Router.generator function. To do so, pass the function reference to the onGenerate parameter like: onGenerateRoute: router.generator.

下篇继续写。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容