Flutter路由栈和生命周期解析

作者: zhx喜籽 | 来源:发表于2020-02-12 11:21 被阅读0次

什么是路由

路由(Routes)是什么?路由是屏幕或应用程序页面的抽象。
Flutter 使我们能够优雅地管理路由主要依赖的是 Navigator(导航器)类。这是一个用于管理一组具有某种进出规则的页面的 Widget,也就是说用它我们能够实现各个页面间有规律的切换。而这里的规则便是在其内部维护的一个“ 路由栈”。
命名路由

在一般应用中,我们用的最多的还是命名路由,它是将应用中需要访问的每个页面命名为不重复的字符串,我们便可以通过这个字符串来将该页面实例推进路由。
例如:

new MaterialApp(
  home: new Screen1(),
  routes: <String, WidgetBuilder> {
    '/screen1': (BuildContext context) => new Screen1(),
    '/screen2' : (BuildContext context) => new Screen2(),
    '/screen3' : (BuildContext context) => new Screen3(),
    '/screen4' : (BuildContext context) => new Screen4()
  },
)

路由栈

Navigator维护了一个堆栈,来保存路由跳转的状态。
screen1跳转到screen2

 Navigator.pushNamed(context, '/screen2') 
image

退出路由pop
Navigator.pop()

image

切勿用pushNamed替代pop,不然就会出现下面的情况了。

image

生命周期

简单地聊完路由栈,接下来介绍 StatefulWidget一系列的生命周期。

image

上图就是 State 的生命周期图。

StatefulWidget.createState()

Framework 通过调用 StatefulWidget.createState() 来创建一个 State。

initState()
新创建的 State 会和一个 BuildContext 产生关联,此时认为 State 已经被安装好了,initState() 函数将会被调用。通常,我们可以重写这个函数,进行初始化操作

didChangeDependencies()
在 initState() 调用结束后,这个函数会被调用。事实上,当 State 对象的依赖关系发生变化时,这个函数总会被 Framework 调用。

build()
经过以上步骤,系统认为一个 State 已经准备好了,就会调用 build() 来构建视图。我们需要在这个函数中,返回一个 Widget。

deactivate()
当 State 被暂时从视图树中移除时,会调用这个函数。页面切换时,也会调用它,因为此时 State 在视图树中的位置发生了变化,需要先暂时移除后添加。⚠️注意,重写的时候必须要调用 super.deactivate()。

dispose()
当 State 被永久的从视图树中移除,Framework 会调用该函数。在销毁前触发,我们可以在这里进行最终的资源释放。在调用这个函数之前,总会先调用 deactivate()。⚠️注意,重写的时候必须要调用 super.dispose()

didUpdateWidget(covariant T oldWidget)
当 widget 的配置发生变化时,会调用这个函数。比如,Hot-reload 的时候就会调用这个函数。这个函数调用后,会调用 build()。

setState()
当我需要更新 State 的视图时,需要手动调用这个函数,它会触发 build()
一般情况下我们用的最多的是initState,build,deactivate,dispose,setState。接下来也主要讲initState以及dispose在路由跳转过程中的触发条件。

路由跳转时的initState,deactivate,dispose
一开始我们是这么写的

@override
void initState() {
    super.initState();
    print('------initstate--------');
}

void deactivate() {
    super.deactivate();
    print('-----deactivate----');
}

void dispose() {
    super.dispose();
    print('----dispose--------');
}

当我们通过pushNamed跳转到其他路由,发现deactivate触发了,但是dispose并没有触发,并且再次通过pushNamed回到本页的时候,initstate也并没有再次执行。
写多了Vue单页面应用的同学,应该知道这其实很让人困扰。我们很多时候需要像Vue一样,在created的时候初始化数据,在beforeDestroy的时候移除页面一些监听事件或者销毁定时器,防止内存泄露。

让我们回到生命周期说明那里:

deactivate() 当 State 被暂时从视图树中移除时,会调用这个函数。
dispose()当 State 被永久的从视图树中移除,Framework 会调用该函数。

此时是不是恍然大悟!pushNamed只是暂时把视图移除了,并没有彻底移除,所以导致了一些奇怪的问题(前提是你跟我一样,业务上需要控制页面的初始化和销毁)

那怎么办。此时popAndPushNamed闪亮登场!用它替代pushNamed,你就会发现该触发的事件都触发了~

popAndPushNamed将当前路由弹出并跳转到新的路由,彻底移除旧路由。
还有类似的方法pushReplacementNamed,pushNamedAndRemoveUntil等,就不赘述了。
取消导航Header的返回键

 AppBar(automaticallyImplyLeading: false)

WillPopScope取消Android物理返回键
这个方法也可以取消iOS默认左右滑动切换路由。

 Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () async {
          return false;
        },
        child: Scaffold(
            // Your Code
        )
    );
}

作者:Harry_Chen

链接:https://juejin.im/post/5df74f7cf265da33d645b307

来源:掘金

相关文章

  • Flutter路由栈和生命周期解析

    什么是路由 路由(Routes)是什么?路由是屏幕或应用程序页面的抽象。Flutter 使我们能够优雅地管理路由主...

  • flutter路由

    在Flutter中,导航器管理应用程序的路由栈。将路由推入(push)到导航器的栈中,将会显示更新为该路由页面。 ...

  • Flutter中管理路由栈的方法和应用

    本文首先讲的Flutter中的路由,然后主要讲下Flutter中栈管理的几种方法。 了解下Route和Naviga...

  • 华云

    一,vue路由守卫的生命周期1,全局的前置路由守卫 router.beforeEach()2, 全局解析守卫 ...

  • flutter 导航以及传参方式

    flutter 导航方式有基本路由和命名路由1、基本路由 ============================...

  • [Flutter开发]03.Flutter中的路由管理

    Flutter中的路由管理,就是管理页面之间如何跳转。无论是Android还是iOS,导航管理都会维护一个路由栈,...

  • flutter手写一个非侵入式Drawer

    总体思路 侧滑控件的实现原理: Flutter中Navigator是用来控制路由栈的,使用方式如下: push接收...

  • Flutter 路由 函数解析

    都是 Navigator 的函数: 在使用 Navigator 函数时一定先要在 main 的MyAPP 中注册一...

  • Flutter 路由源码解析

    前言 这是博客《Flutter路由 - Navigator 》的番外篇,如果你没有看过主篇真的不建议你直接看这篇文...

  • flutter_boost

    混合开发要点 flutter engine复用 flutter路由和原生导航同步 flutter和原生数据传输->...

网友评论

    本文标题:Flutter路由栈和生命周期解析

    本文链接:https://www.haomeiwen.com/subject/frbqfhtx.html