概要
在运行时,FragmentManager 可以添加、删除、替换和使用片段执行其他操作以响应用户交互。
您提交的每组片段更改称为一个事务,您可以使用 FragmentTransaction 该类提供的 API 指定在事务中执行的操作
您可以将多个操作分组到一个事务中——例如,一个事务可以添加或替换多个片段
创建和操作事务
通过调用 FragmentManagerbeginTransaction() 获取FragmentTransaction的实例,如下例所示:
1 2 FragmentManager fragmentManager = ...FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
每个人的最终调用都FragmentTransaction必须提交事务。该commit()调用FragmentManager表示所有操作都已添加到事务中
1 2 3 4 5 6 FragmentManager fragmentManager = ...FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.commit();
片段状态更改重新排序
每个都 FragmentTransaction 应该使用 setReorderingAllowed(true) 允许片段状态更改重排序
1 2 3 4 5 FragmentManager fragmentManager = ...fragmentManager.beginTransaction() ... .setReorderingAllowed(true ) .commit();
为了行为兼容性,默认情况下不启用重新排序标志。
但是,它需要允许FragmentManager正确执行您的FragmentTransaction,
特别是当它在后台堆栈上运行并运行动画和过渡时。
启用该标志可确保如果多个事务一起执行,任何中间片段(即添加然后立即替换的片段)
不会经历生命周期更改或执行其动画或转换。
请注意,此标志会影响事务的初始执行和使用 撤销事务popBackStack()
添加和删除片段
调用 add()将片段添加到 FragmentManager。此方法接收片段容器的 ID ,以及您希望添加的片段的类名。
添加的片段被移动到 RESUMED 状态。
强烈建议容器是 FragmentContainerView 视图层次结构的一部分。
要从主机中删除片段,请调用 remove() 方法传入一个片段实例
该实例是由 findFragmentById() or findFragmentByTag()方法找到的
如果片段的视图先前已添加到容器中,则此时视图将从容器中删除。移除的片段被移动到 DESTROYED 状态。
用于 replace() 将容器中的现有片段替换为您提供的新片段类的实例。
调用replace()相当于调用 remove() 先移除容器中的片段,然后将新片段添加到同一个容器中。
以下代码片段显示了如何将一个片段替换为另一个片段:
1 2 3 4 5 6 7 8 9 10 FragmentManager fragmentManager = ...FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.setReorderingAllowed(true ); transaction.replace(R.id.fragment_container, ExampleFragment.class, null ); transaction.commit();
在这个例子中,一个新的实例 ExampleFragment 替换了当前位于由
标识的布局容器中的片段(如果有的话) R.id.fragment_container
注意:强烈建议始终使用采用 Class 而不是片段实例的片段操作,
以确保创建片段的相同机制也用于从保存状态恢复片段。
有关更多详细信息,请参阅 FragmentManager
默认情况下,在 FragmentTransaction 中所做的更改不会添加到后台堆栈。
要保存这些更改,您可以调用 addToBackStack()
提交异步
调用 commit() 不会立即执行事务。事务被安排在主 UI 线程上运行,只要它能够这样做。
但是,如有必要,您可以调用 commitNow() 以立即在您的 UI 线程上运行片段事务。
请注意,commitNow 与 addToBackStack 是不兼容的. 或者,您可以通过调用 executePendingTransactions()
执行所有尚未运行的由FragmentTransactions提交的事务。
这种方法与 addToBackStack 是兼容的
对于绝大多数用例,使用 commit() 就足够了
执行顺序
在 FragmentTransaction 中执行操作的顺序很重要,
尤其是在使用setCustomAnimations().
此方法将给定的动画应用于其后的所有片段操作
1 2 3 4 5 6 getSupportFragmentManager().beginTransaction() .setCustomAnimations(enter1, exit1, popEnter1, popExit1) .add(R.id.container, ExampleFragment.class, null ) .setCustomAnimations(enter2, exit2, popEnter2, popExit2) .add(R.id.container, ExampleFragment.class, null ) .commit()
显示和隐藏
使用 FragmentTransaction 中的 show() hide() 方法显示和隐藏已添加到容器的片段的视图
这些方法设置片段视图的可见性,而不影响片段的生命周期
虽然您不需要使用片段事务来切换片段中视图的可见性,
但这些方法对于您希望更改可见性状态与后台堆栈上的事务相关联的情况很有用
附加和分离
FragmentTransaction 方法 detach() 将片段与 UI 分离,破坏其视图层次结构。
片段保持与放入回退栈时相同的状态(STOPPED)。这意味着片段已从 UI 中删除,但仍由片段管理器管理。
attach() 方法重新附加之前分离的片段。这会导致其视图层次结构被重新创建、附加到 UI 并显示。
由于 FragmentTransaction 被视为单个原子操作集,
因此对同一事务中的同一片段实例的同时调用 detach 和 attach 会相互抵消,从而避免了片段 UI 的破坏和立即重建。
如果想要实现立即 detach 然后 attach 操作需使用单独的事务分别 commit()
然后使用 executePendingOperations() 方法立即执行挂起的事务