【Fragment 多返回栈发布】千呼万唤始出来,支持多返回栈的 Navigat...

Flywith24

共 2544字,需浏览 6分钟

 ·

2021-08-18 19:27

前言

很高兴见到你 👋

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

让我们开始吧~

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

ddae376fae492adb03618a39ce34857b.webp

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

  • 【背上Jetpack之OnBackPressedDispatcher】Fragment 返回栈预备篇
  • 【背上Jetpack之Fragment】从源码的角度看Fragment 返回栈 附多返回栈demo
  • 【背上Jetpack】绝不丢失的状态 androidx SaveState ViewModel-SaveState 分析
  • 【背上Jetpack之Fragment】从源码角度看 Fragment 生命周期 AndroidX Fragment1.2.2源码分析
  • 【译】Fragment 的重大重构 —— 介绍 Fragment 新的状态管理器
  • 【Fragment多返回栈】开篇,Navigation 所谓的重建问题是什么?
Fragment 支持多返回栈后解决了什么问题?

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

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

356cd51be3d5366c81d54bee4f9da128.webp

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

caa619b0c1b23333e54d588ca055ca88.webp923f7baaebb9c5293e2e5a5ff020b866.webp

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

9977a7b6c274b1281c926318635aa4f9.webp

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

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

f46aeb862689e5c2893b4b749796a811.webp

效果如下:

396218b64561f818ef5d4a1a5218e83d.webpFragment 支持多返回栈后就不重建了吗?

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

e452c680bc4254715ef456b44307dea3.webp

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

8744dd05757975d21db518fd7ffc8dda.webp

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

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

☝ 划重点

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

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

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

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

067a51662a2aef96a9bf3129a37d9a2e.webp

假设我们进行如下操作:

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

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

858a350b23387b3c6ace010f05117a96.webp

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

41e92634598c07762cce7922f9748ba1.webp

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

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

603a2d53008c76656d1960897566a9a1.webp

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


这样表述你明白了吗? 😉

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


一点广告(内推时间)

我们是 快手主站技术部团队,负责快手主站和部分独立业务的工程研发。团队整合客户端、服务端、Web端,实现与业务更灵活高效的合作,通过稳定的基础平台、高效的业务开发、前沿的技术探索,支撑快手核心业务的快速发展。

基本福利

  • 全额六险一金,周末双休,加班双倍工资
  • 16 薪起 + 2000 房补 + 包三餐
  • 工作环境舒适,园区内部星巴克、罗森、赛百味
  • 16 寸顶配 MacBook Pro,每日下午茶,无限量免费冰淇淋咖啡奶茶

基本要求

  • 本科(大牛可无视)
  • JD 列表

从 JD 中挑选岗位,发简历和意向的岗位链接到我微信:Flywith24

承诺

  • 实时跟踪并反馈面试进度
  • 帮忙改简历
  • Android 开发者可以免费进入我的知识星球
878a77b57ef68bfa8061a4c9247360e1.webp
关于我

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

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

  • 掘金
  • 小专栏
  • Github
  • 微信:Flywith24


浏览 35
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报