【背上Jetpack之Fragment】从源码的角度看Fragment 返回栈 附多返回栈demo

本文从源码角度详细探讨了Fragment的返回栈管理,包括返回栈中的元素、管理返回栈的FragmentManager、如何触发返回操作。重点分析了popBackStack系列方法的逻辑,并介绍了单返回栈和多返回栈的实现方式。最后讨论了Fragment如何拦截Activity的返回逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章

【背上Jetpack】Jetpack 主要组件的依赖及传递关系

【背上Jetpack】AdroidX下使用Activity和Fragment的变化

【背上Jetpack之Fragment】你真的会用Fragment吗?Fragment常见问题以及androidx下Fragment的使用新姿势

【背上Jetpack之Fragment】从源码角度看 Fragment 生命周期 AndroidX Fragment1.2.2源码分析

【背上Jetpack之OnBackPressedDispatcher】Fragment 返回栈预备篇

前言

上一篇 我们介绍了 OnBackPressedDispather ,那么今天我们来正式地从源码的角度看看 fragment 的返回栈吧。由于其主流程和生命周期差不多,因此本文将详细地分析返回栈相关的源码,并插入大量源码。建议将生命周期流程熟悉后阅读本文。文末提供单返回栈和多返回栈的 demo

如果您对 activity 对任务栈和返回栈不是很了解,可以移步 Tasks and the Back Stack

小问号你是否有很多朋友?

在分析源码之前,我们先来思考几个问题。

  • 返回栈中的元素是什么?
  • 谁来管理 fragment 的返回栈?
  • 如何返回?

返回栈中的元素是什么?

返回栈,顾名思义,是一个栈结构。所以我们要搞清楚,这个栈结构到底存的是什么。

我们都知道,使用 fragment 的返回栈需要调用 addToBackStack("") 方法

从源码角度看 Fragment 生命周期 一文中,我们提到了 FragmentTransaction ,它是一个「事务」的模型,事务可以回滚到之前的状态。所以当触发返回操作时,就是将之前提交的事务进行回滚。

FragmentTransaction 的实现类为 BackStackRecord ,所以 fragment 的返回栈其实存放的就是 BackStackRecord

作为返回栈的元素,BackStackRecord 实现了FragmentManager.BackStackEntry 接口

BackStackRecord

BackStackRecord 的定义我们可以发现 BackStackRecord 有三种身份

  • 继承了 FragmentTransaction,即是事务,保存了整个事务的全部操作
  • 实现了 FragmentManager.BackStackEntry ,作为回退栈的元素
  • 实现了OpGenerator ,可以生成 BackStackRecord 列表,后文详细介绍

谁来管理 fragment 的返回栈?

我们已经知道 fragment 的返回栈其实存放的是 BackSrackRecord , 那么谁来管理 fragment 的返回栈?

FragmentManager 用于管理 fragment ,所以 fragment 返回栈也应该由 FragmentManager 管理

//FragmentManager.java
ArrayList<BackStackRecord> mBackStack;

其实触发 fragment 的返回逻辑有两种途径

  • 开发主动调用 fragment 的返回方法

  • 用户按返回键触发

后文我们会从这两个角度分析一下 fragment 中的返回栈逻辑究竟是怎样的

如何返回?

我们已经知道返回栈中的元素是 BackStackRecord ,也清楚了是 FragmentManager 来管理返回栈。那么如果让我们来实现「返回」逻辑,应该如何做?

首先我们要清楚所谓的「返回」是对事务的回滚,即 对 commit 事务的内部逻辑执行相应的「逆操作」

例如

addFragment←→removeFragment

showFragment←→hideFragment

attachFragment←→detachFragment

有的小伙伴可能会疑惑 replace 呢?

expandReplaceOps 方法会把 replace 替换(目标 fragment 已经被 add )成相应的 remove 和 add 两个操作,或者(目标 fragment 没有被 add )只替换成 add 操作

popBackStack 系列方法

FragmentManager 中提供了popBackStack 系列方法

popBackStack系列方法

是否觉得很眼熟?提交事务也有类似的api,commit 系列方法

commit系列方法

这里分别提供了同步和异步的方法,可能有读者会疑惑,同样是对事务的操作,一个为提交,一个为回滚,为什么一个封装到了 FragmentManager 中,一个却在 FragmentTransaction 中。既然都是对事务的操作,应该都放在FragmentManager 中。我认为可能为了api使用的方便,使得 FragmentManager 开启事务的链式调用一气呵成。各位有什么想法欢迎在评论区留言。

这里主要介绍一下 popBackStack(String name, int flag)

name 为 addToBackStack(String name) 的参数,通过 name 能找到回退栈的特定元素,flag可以为 0 或者FragmentManager.POP_BACK_STACK_INCLUSIVE,0 表示只弹出该元素以上的所有元素,POP_BACK_STACK_INCLUSIVE 表示弹出包含该元素及以上的所有元素。这里说的弹出所有元素包含回退这些事务。如果这么说比较抽象的话,看图

//flag 传入0,弹出 ♥2 上的所有元素
childFragmentManager.popBackStack("♥", 0)

flag为0

//flag 为 POP_BACK_STACK_INCLUSIVE 弹出包括该元素及及以上的元素
childFragmentManager.popBackStack("♥",  androidx.fragment.app
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值