【Fragment 多返回栈发布】千呼万唤始出来,支持多返回栈的 Navigation 就不重建了吗?

8,221 阅读3分钟

前言

很高兴见到你 👋

我是 Flywith24,这是我在掘金发布的 第56篇 原创文章。

本文是 Fragment 多返回栈系列的第二篇,主要介绍最新的 Fragment 多返回栈 API 以及新 API 是否仍会出现 Navigation Fragment 重建的问题。

让我们开始吧~

随着 Ian Lake 将这个 2018 年 5 月提的 issue 标记为 fixed,Android 终于支持了 Fragment 的多返回栈。

如果你是第一次接触 Fragment 多返回栈,可以移步以下内容以获取必要的前置知识:

Fragment 支持多返回栈后解决了什么问题?

我们来简单回顾一下 Navigation 管理 「平级界面」 会遇到什么问题。详细内容可以 移步这里

我们使用 Android Studiobottom navigation 模板快速创建一个 project

该 project 由一个 Activity(MainActivity) 以及三个 Fragment(HomeDashboardNotifications)组成,其中每个 tab 对应的父 Fragment 均可跳转到对应的子 Fragment 中:

每次点击底部 tab,对应的 Fragment 都会重新创建新的实例,这会导致当前 tab 之前存在的状态丢失,效果如下图:

上图中,在 Home tab 中点击进入 HomeChildFragment,此时点击 dashboard tab 并返回,home tab 对应的 Fragment 恢复成原来的状态!这种行为完全不符合用户的预期

我们将 navigation 库的版本调整到 2.4.0(目前在 alpha 阶段),该问题得到解决。

效果如下:

Fragment 支持多返回栈后就不重建了吗?

最近很多小伙伴反馈说使用版本的 Navigation 库仍然存在「重建」的问题。

我们使用新版本 Navigation 并点击每个 tab 查看当前 fragment 的实例:

上图可以看到,点击 dashboardnotifications tab 时,对应的 fragment 实例发生了变化(重复点击 home 并没重建 fragment,这个我们之后源码分析篇讨论)

新版本的 Navigation 仍会导致 fragment 的重建!

☝ 划重点

新版本的 Navigation 是如何恢复状态的?

通过前文我们已经知道新版本的 Navigation 仍会有 Fragment 的重建问题,那么如何使重建的 Fragment 能够恢复之前的状态?

答案呼之欲出:Android 的 SavedState 机制。更多关于 SavedState 的内容,可移步

通过加入对 savedInstanceState 是否为空的判断日志我们了解到,每次重建 Fragment 时,savedInstanceState 不为空:

假设我们进行如下操作:

  1. 在初始化状态点击 dashboard tab 进入 DashboardFragment,然后进入 dashboard 的详情页 DashboardChildFragment
  2. 之后点击 notifications tab 进入到 NotificationsFragment
  3. 最后点击 dashboard 返回

步骤 1 执行完毕时 Saved State 与返回栈的状态:

步骤 2 执行完毕时 Saved State 与返回栈的状态:

步骤 2 执行时,Fragment Manager 会调用新 API fragmentManager.saveBackStack("dashboard")dashboard 这个子返回栈(姑且这样称呼它)存入 Saved State

步骤 3 执行完毕时 Saved State 与返回栈的状态:

步骤 3 执行时,Fragment Manager 会调用新 API fragmentManager.saveBackStack("notifications")fragmentManager.restoreBackStack("dashboard") 保存 notifications 的子返回栈,恢复 dashboard 的子返回栈。


这样表述你明白了吗? 😉

具体的实现逻辑我们将在源码篇介绍,敬请期待。

关于我

人总是喜欢做能够获得正反馈(成就感)的事情,如果感觉本文内容对你有帮助的话,麻烦点亮一下👍,这对我很重要哦~

我是 Flywith24人只有通过和别人的讨论,才能知道我们自己的经验是否是真实的,加我微信交流,让我们共同进步。