首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大前端开发中的路由管理之五:Flutter篇

大前端开发中的路由管理之五:Flutter篇

作者头像
QQ音乐技术团队
发布2021-11-18 10:40:07
2.1K0
发布2021-11-18 10:40:07
举报

        前面大家了解了Web和Native端的路由管理,这篇文章出场的是大前端领域备受开发者喜欢的新秀Flutter。

        Flutter作为一款跨平台UI框架,借鉴了React(Web开发框架)的响应式的UI框架设计思想等。在Flutter中,一切皆是Widget(组件),其中StatefulWidget(有状态的组件)和React中的组件类似,可以通过数据变化去手动更新视图,Flutter路由管理实现的核心组件Navigator就是这样的一个StatefulWidget。

1、认识Flutter路由导航

1.1  Route(路由页面)

页面的包装类,一个页面想要被路由统一管理,必须包装为一个Route,Route并不是一个widget,但是在页面栈实现中起到至关重要的作用,它是一个抽象类,其继承关系如下,其中每一层都处理了与其相关的一些逻辑。

  • OverlayRoute:在导航器的Overlay中显示控件的路由。主要将路由转换为Widget插入控件树。
  • TransitionRoute:具有进入和退出过渡动画的路由。主要处理路由过渡动效。
  • ModalRoute:阻止与下层路由交互的路由。它覆盖整个导航器。但它们不一定是不透明的。例如一个对话框。主要处理事件的拦截。
  • PageRoute:替换整个屏幕的模态路由。由它派生出了我们熟悉的MaterialPageRoute,主要用于Flutter的页面切换。
  • PopupRoute:在当前路由上覆盖Widget的模态路由。主要用于弹出框,对话框之类。

1.2  Navigator(导航器)

管理所有的Route的Widget,实现路由导航的核心widget。它维护了一个路由栈集合(List<_RouteEntry>),当你调用push,pop方法时,Navigator都会以栈的方式对这个集合进行添加或删除,并通过路由栈状态变化实现对页面栈的更新。

  • 我们不需要手动创建Navigator,开发中使用的MaterialApp、CupertinoApp、WidgetsApp它们默认是有插入Navigator的,我们在需要的时候可以直接使用Navigator.of(context)。Navigator的widget构建流程如下: 
  • 当我们想使用导航操作时,Navigator提供了如下几个常用的方法:
// 路由跳转:传入一个路由对象Future<T> push<T extends Object>(Route<T> route)
// 路由跳转:传入一个名称(命名路由)Future<T> pushNamed<T extends Object>(  String routeName, {    Object arguments,  })
// 路由返回:可以传入一个参数bool pop<T extends Object>([ T result ])

1.2  Overlay(页面栈)

真正的页面栈,Overlay可以翻译为叠加层或覆盖层。按照官方的解释,它是一个可以独立管理的覆盖层堆栈。它维护一个页面栈集合(List<OverlayEntry>),实现页面栈到widget的转换过程,它同时也拥有一个私有类_Theatre来进行页面widget的绘制。

  • _Theatre:它的名字非常形象的表达了它的功能:剧院。你有很多组件以一层层覆盖的模式绘制在界面上时,如果其中某一层的组件以全屏不透明的模式绘制在界面上,那它下层的组件就不需要再进行绘制了。

2、Flutter路由管理实现

2.1 导航器初始化

        Navigator是一个有状态的widget,NavigatorState在初始化时主要做了两件事:

  1. 根据配置参数创建初始化路由,初始化路由会放入_history(路由栈)里面去
  2. 调用_flushHistoryUpdates方法刷新路由栈

        这里最为复杂也是最核心的就是这个刷新路由栈的方法,该方法会根据不同的路由生命周期(_RouteLifecycle)做相应处理。初始化创建的路由会设置其路由状态为_RouteLifecycle.add,在_flushHistoryUpdates中会调用route的插入方法将根路由转换为OverlayEntry对象,插入到Overlay管理的页面栈中并通知Overlay更新视图。下面是伪代码,可以简单了解一下:

// [NavigatorState] 伪代码List<_RouteEntry> _history = <_RouteEntry>[]; // 路由栈集合void initState() {  _history.addAll([_RouteEntry(route, _RouteLifecycle.add)]);// 1.依据初始化构建参数创建初始化路由_RouteEntry,放入_history集合  _flushHistoryUpdates(); // 2.更新页面栈}void _flushHistoryUpdates() {  // 1.遍历路由栈集合  // 2.状态为_RouteLifecycle.add的路由调用  while(遍历条件) {    switch (路由状态) {      case _RouteLifecycle.add: // 执行add对应方法 初始化跟路由会执行      case _RouteLifecycle.push: // 执行push动作对应方法      ...    }  }  // 3.对应路由监听器触发,无用路由和页面销毁,overlay组件更新}Widget build() {  // 构建Overlay 并通过一个_overlayKey持有OverlayState}

2.2 页面绘制

        Overlay在Navigator的build方法中创建,Overlay会遍历OverlayEntry列表,将保存的实体信息对象封装为_OverlayEntryWidget控件,最终将包含_OverlayEntryWidget的列表交给_Theatre控件插入控件树中用于渲染。

        _Theatre控件将页面分为了两种,一种是舞台上的(onstage)演员,另一种则是舞台下的(offstage)观众。当某个包装页面的OverlayEntry的opaque属性为true时,表示占满全屏且不透明,那么以它为分界线,它之下的所有页面都不需要绘制了(因为被挡住了看不见)。如果OverlayEntry的maintainState属性也为true,则被分到舞台下的观众那一组,否则,没有进入剧院的资格。

2.3 导航操作

        前面我们了解了Navigator的初始化构建流程,对于页面栈刷新已经有了一些认识,接下来我们来看看push方法都做了些什么。

Future<T> push<T extends Object>(Route<T> route) {  // 使用_RouteEntry包装传进来的路由然后入栈,设置路由状态为push  _history.add([_RouteEntry(route, _RouteLifecycle.push)]);  _flushHistoryUpdates();// 刷新路由栈  ...}

        在刷新路由栈的时候push状态的路由也会插入两个新的OverlayEntry,并在所有操作完成后触发Overlay更新。下图是push前后各widget中的栈的变化。

3、Flutter路由管理实现总结

        从以上流程实现可以看出,Flutter页面栈的实现依赖于:

  • Navigator持有路由栈,提供导航方法,当路由栈发生变化时同步更新页面栈。
  • Overlay持有页面栈,它实现页面栈到渲染用widget集合的转换过程,并能够接受到路由栈更新的通知去同步更新视图。
  • _Theatre负责对页面widget进行动态构建和绘制,保证渲染性能。

        上面讲到是纯Flutter中路由管理的实现,但是在我们开发中可能还会遇到Flutter-Native混编的模式,对这块感兴趣的同学们可以在我们团队这篇文章 Flutter 核心原理与混合开发模式 中解锁更多知识。


至此,我们了解到了Flutter端是如何去实现路由管理的,那么,就请期待我们最后一篇文章《大前端开发中的路由管理之六:总结篇》

参考资料

[1]  Flutter路由源码剖析

https://zhuanlan.zhihu.com/p/208788731

[2] Flutter路由导航

https://zhuanlan.zhihu.com/p/144820879

QQ音乐招聘 Android / iOS 客户端开发,点击左下方“查看原文”投递简历~

也可将简历发送至邮箱:tmezp@tencent.com


文末为大家推荐一个技术号《腾讯音乐天琴实验室》,TME天琴实验室致力于对业内前沿科技如AI等方向进行相关研发,持续推出新技术提升TME旗下QQ音乐等平台的音乐视听体验,对音视频相关AI研发感兴趣的同仁们一起交流学习起来吧!!!

↓   ↓   ↓

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯音乐技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1  Route(路由页面)
  • 1.2  Navigator(导航器)
  • 1.2  Overlay(页面栈)
    • 2.1 导航器初始化
      • 2.2 页面绘制
        • 2.3 导航操作
        • 参考资料
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档