android学习笔记:activity(6)-fragment manager

本文介绍了Android中FragmentManager的使用,包括管理Fragment的添加、移除和替换,以及返回堆栈的操作。FragmentManager允许在Activity中进行Fragment的交互,每个FragmentActivity可以通过getSupportFragmentManager()获取它。文中还讨论了Fragment如何托管子Fragment,以及FragmentTransaction如何处理用户交互。返回栈堆的管理和Fragment事务的原子化操作是FragmentManager的重要特性,当用户按下返回键时,事务会从栈中弹出。此外,还提到了如何保存和恢复返回栈,以及如何处理配置更改对Fragment的影响。

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

1.FragmentManager 类负责对应用的 Fragment 执行一些操作,如添加、移除或替换它们,以及将它们添加到返回堆栈。

2.每个FragmentActivity及其子类(如AppCompatActivity)都可以通过getSupportFragment()方法访问FragmentManager

3.fragment也能够托管一个或多个子fragment,在fragment内,可以通过getChildFragmentManager()获取对管理Fragment子级的FragmentManager的引用。如果需要访问其他宿主FragmentManager,可以通过getParentFragmentManager()方法

图 1. 两个界面布局示例,显示了 Fragment 与其宿主 Activity 之间的关系。

图1显示了两个示例,每个示例中都有一个activity宿主。这两个示例中的宿主activity都以ButtomNagigationView的形式向用户显示顶级导航,该视图负责以应用中的不同屏幕换出宿主Fragment,其中每个屏幕都实现为单独的Fragment.

示例1中的宿主Fragment托管两个子Fragment,这些Fragment构成拆分视图屏幕。示例2中的宿主Fragment托管一个子Fragment,该Fragment构成滑动视图的显示Fragment

基于此设置,可以将每个宿主视为具有与其关联的FragmentManager,用于管理其子Fragment,如下图所示

 

3.一般来说,应用应该有应用项目中的一个或少数几个activity组成,其中每个activity表示一组相关的屏幕。Activity可能会提供一个点来防止顶级导航,并提供一个位置来限定ViewModels以及Fragment之间的其他视图状态的范围。应用中的每个目的地应由一个Fragment表示。(如果想要一次显示多个fragment,应使用子fragment,他们由目的地fragment及其子fragment管理器进行管理)

4.Fragment管理Fragment返回栈堆。在运行时,FragmentManager可以执行添加或移除Fragment等返回栈堆操作来响应用户互动。每一组更改作为一个单元(称为FragmentTransaction)一起提交。

5.当用户按设备上的“返回”按钮时,或者当您调用 FragmentManager.popBackStack() 时,最上面的 Fragment 事务会从堆栈中弹出。换句话说,事务是反转的。如果堆栈上没有更多 Fragment 事务,并且您没有使用子 Fragment,则返回事件会向上传递到 Activity。如果您使用子 Fragment,

6.当对事物调用addToBackStack()时,事物可以包括任意数量的操作,如添加多个Fragment、替换多个容器中的Fragment、等等,在弹出返回栈时,所有这些操作会作为一项原子化操作反转。但是如果在调用popBackStack()之前提交了其他事务,并且没有对事物使用addTobackStack(),则这些操作不会反转,所以在一个FragmentTransaction中,应该避免让影响返回栈堆的事物与不影响返回栈堆的事物交织在一起

7.如果需要在布局容器中显示Fragment,使用FragmentManager创建FragmentTransaction事物,可以进行add(),或replace()操作

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container)
   setReorderingAllowed(true)
   addToBackStack("name") // name can be null
}

        在本例中,ExampleFragment 会替换当前在由 R.id.fragment_container ID 标识的布局容器中的 Fragment(如果有)。将 Fragment 的类提供给 replace() 方法可让 FragmentManager 使用其 FragmentFactory 处理实例化。如需了解详情,请参阅提供依赖项

  setReorderingAllowed(true) 可优化事务中涉及的 Fragment 的状态变化,以使动画和过渡正常运行。如需详细了解如何使用动画和过渡进行导航,请参阅 Fragment 事务使用动画在 Fragment 之间导航

        调用addToBackStack()会将书屋提交到返回栈堆,在其中提供可选名称能够在使用popBackStack()弹回到该特定事物

8.可以使用findFragmentById(0获取对布局容器当前Fragment的引用

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container)
   setReorderingAllowed(true)
   addToBackStack(null)
}

...

val fragment: ExampleFragment =
        supportFragmentManager.findFragmentById(R.id.fragment_container) as ExampleFragment

或者可以为Fragment分配一个唯一的标记,并使用FindFragmentById获取引用。可以在布局定义中使用android:tagXML属性来分配标记,也可以在FragmentTransaction中的add()或replace()操作期间分配标记

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container, "tag")
   setReorderingAllowed(true)
   addToBackStack(null)
}

...

val fragment: ExampleFragment =
        supportFragmentManager.findFragmentByTag("tag") as ExampleFragment

9.在任何给定的时间,只允许一个 FragmentManager 控制 Fragment 返回堆栈。如果应用在屏幕上同时显示多个同级 Fragment,或者应用使用子 Fragment,则必须指定一个 FragmentManager 来处理应用的主要导航。

如需在 Fragment 事务内定义主要导航 Fragment,请对事务调用 setPrimaryNavigationFragment() 方法,并传入一个 Fragment 的实例,该 Fragment 的 childFragmentManager 应具有主要控制权。

将导航结构视为一系列层,其中 Activity 作为最外层,封装下面的每一层子 Fragment。每一层都必须有一个主要导航 Fragment。当发生返回事件时,最内层控制导航行为。一旦最内层再也没有可从其弹回的 Fragment 事务,控制权就会回到外面的下一层,此过程会一直重复,直至到达 Activity 为止。

请注意,当同时显示两个或更多 Fragment 时,其中只有一个可以是主要导航 Fragment。如果将某个 Fragment 设为主要导航 Fragment,会移除对先前 Fragment 的指定。在上例中,如果您将详情 fragment 设为主要导航 fragment,就会移除对主 fragment 的指定。

10.FragmentManager可以通过saveBackStack()和restoreBackStack()方法支持多个返回栈堆。这两种方法可以通过保存一个返回栈堆并恢复另一个返回栈堆来在返回栈堆之间进行交换(注:或者,也可以使用 NavigationUI 组件,该组件会自动处理对底部导航栏的多个返回堆栈支持。)

11.除非使用 addToBackStack() 传递 fragment 事务的可选名称,否则不能使用 saveBackStack() 和 restoreBackStack()。且只能将 saveBackStack() 用于调用 setReorderingAllowed(true) 的事务,以确保可以将事务还原为单一原子操作。

supportFragmentManager.restoreBackStack("replacement")

12.添加fragment时,可以手动实例化Fragment并将其添加到FragmentTransaction

fragmentManager.commit {
    // Instantiate a new instance before adding
    val myFragment = ExampleFragment()
    add(R.id.fragment_view_container, myFragment)
    setReorderingAllowed(true)
}

13.在配置更改期间,activity及其所有Fragment都会被销毁,然后使用最适用的android资源重新创建,FragmentManager会自动处理这些事情

14.

默认情况下,FragmentManager 使用框架提供的 FragmentFactory 实例化 Fragment 的新实例。此默认工厂使用反射来查找和调用 Fragment 的无参数构造函数。这意味着,您无法使用此默认工厂为 Fragment 提供依赖项。这也意味着,默认情况下,在重新创建过程中,不会使用您首次创建 Fragment 时所用的任何自定义构造函数。

如需为 Fragment 提供依赖项或使用任何自定义构造函数,您必须创建自定义 FragmentFactory 子类,然后替换 FragmentFactory.instantiate。您随后可以将 FragmentManager 的默认工厂替换为您的自定义工厂,它随后用于实例化 Fragment。

假设您有一个 DessertsFragment,负责显示您家乡受欢迎的甜点。我们假设 DessertsFragment 依赖于 DessertsRepository 类,该类可为其提供向用户显示正确界面所需的信息。

您可以将 DessertsFragment 定义为在其构造函数中需要 DessertsRepository 实例。

15.fragment提供依赖项这一块暂时理解有些问题,需要后期返回理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值