Fragment
表示 FragmentActivity
中的行为或界面的一部分。您可以在一个 Activity 中组合多个片段,从而构建多窗格界面,并在多个 Activity 中重复使用某个片段。您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段(这有点像可以在不同 Activity 中重复使用的“子 Activity”)。
片段必须始终托管在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。例如,当 Activity 暂停时,Activity 的所有片段也会暂停;当 Activity 被销毁时,所有片段也会被销毁。不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您可以独立操纵每个片段,如添加或移除片段。当执行此类片段事务时,您也可将其添加到由 Activity 管理的返回栈 — Activity 中的每个返回栈条目都是一条已发生片段事务的记录。借助返回栈,用户可以通过按返回按钮撤消片段事务(后退)。
当您将片段作为 Activity 布局的一部分添加时,其位于 Activity 视图层次结构的某个 ViewGroup
中,并且片段会定义其自己的视图布局。您可以通过在 Activity 的布局文件中声明片段,将其作为 元素插入您的 Activity 布局,或者通过将其添加到某个现有的
ViewGroup
,利用应用代码将其插入布局。
本文介绍如何在开发应用时使用片段,包括如何在将片段添加到 Activity 返回栈时保持其状态、如何与 Activity 及 Activity 中的其他片段共享事件、如何为 Activity 的应用栏发挥作用等等。
如需了解有关处理生命周期的信息(包括最佳实践的相关指导),请参阅以下资源:
使用具有生命周期感知能力的组件处理生命周期
应用架构指南
支持平板电脑和手机
设计原理
Android 在 Android 3.0(API 级别 11)中引入了片段,主要目的是为大屏幕(如平板电脑)上更加动态和灵活的界面设计提供支持。由于平板电脑的屏幕尺寸远胜于手机屏幕尺寸,因而有更多空间可供您组合和交换界面组件。利用片段实现此类设计时,您无需管理对视图层次结构做出的复杂更改。通过将 Activity 布局分成各个片段,您可以在运行时修改 Activity 的外观,并在由 Activity 管理的返回栈中保留这些更改。现在,您可以通过片段支持库获取大量片段。
例如,新闻应用可以使用一个片段在左侧显示文章列表,使用另一个片段在右侧显示文章 — 两个片段并排显示在一个 Activity 中,每个片段都拥有自己的一套生命周期回调方法,并各自处理自己的用户输入事件。因此,用户无需使用一个 Activity 来选择文章,然后使用另一个 Activity 来阅读文章,而是可以在同一个 Activity 内选择文章并进行阅读,如图 1 中的平板电脑布局所示。
您应将每个片段都设计为可重复使用的模块化 Activity 组件。换言之,由于每个片段都会通过各自的生命周期回调来定义自己的布局和行为,您可以将一个片段加入多个 Activity,因此,您应采用可复用式设计,避免直接通过某个片段操纵另一个片段。这一点颇为重要,因为模块化片段允许您更改片段的组合方式,从而适应不同的屏幕尺寸。在设计可同时支持平板电脑和手机的应用时,您可以在不同的布局配置中重复使用您的片段,以根据可用的屏幕空间优化用户体验。例如,在手机上,如果不能在同一 Activity 内储存多个片段,则可能必须利用单独的片段来实现单窗格界面。
图 1. 由片段定义的两个界面模块如何适应不同设计的示例:通过组合成一个 Activity 来适应平板电脑设计,通过单独片段来适应手机设计。
例如(仍以新闻应用为例),在平板电脑尺寸的设备上运行时,该应用可以在 Activity A 中嵌入两个片段。不过,手机尺寸的屏幕没有足够的空间来存储两个片段,因此 Activity A 只包含用于显示文章列表的片段,并且当用户选择文章时,它会启动 Activity B,其包含用于阅读文章的第二个片段。因此,应用可通过重复使用不同组合的片段来同时支持平板电脑和手机(如图 1 所示)。
如需详细了解在设计应用时利用不同片段组合来适应不同屏幕配置,请参阅屏幕兼容性概览。
创建片段
图 2. 片段的生命周期(当其 Activity 运行时)。
如要创建片段,您必须创建 Fragment
的子类(或已有其子类)。Fragment
类的代码与 Activity
非常相似。它包含与 Activity 类似的回调方法,如 onCreate()
、onStart()
、onPause()
和 onStop()
。实际上,如果您要将现有 Android 应用转换为使用片段,可能只需将代码从 Activity 的回调方法移入片段相应的回调方法中。
通常,您至少应实现以下生命周期方法:
onCreate()
系统会在创建片段时调用此方法。当片段经历暂停或停止状态继而恢复后,如果您希望保留此片段的基本组件,则应在您的实现中将其初始化。
onCreateView()
系统会在片段首次绘制其界面时调用此方法。如要为您的片段绘制界面,您从此方法中返回的
View
必须是片段布局的根视图。如果片段未提供界面,您可以返回 null。onPause()
系统会将此方法作为用户离开片段的第一个信号(但并不总是意味着此片段会被销毁)进行调用。通常,您应在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。
大多数应用至少应为每个片段实现这三个方法,但您还应使用几种其他回调方法来处理片段生命周期的各个阶段。处理片段生命周期部分对所有生命周期回调方法做了更详尽的阐述。
请注意,用于实现依赖组件生命周期的代码应放在组件本身内,而非直接放在片段回调实现中。请参阅使用具有生命周期感知能力的组件处理生命周期,了解如何让您的依赖组件获得生命周期感知能力。
您可能还想扩展几个子类,而非 Fragment
基类:
DialogFragment
显示浮动对话框。使用此类创建对话框可有效代替使用
Activity
类中的对话框辅助方法,因为您可以将片段对话框纳入由 Activity 管理的片段返回栈,从而使用户能够返回清除的片段。ListFragment
显示由适配器(如
SimpleCursorAdapter
)管理的一系列项目,类似于ListActivity
。该类提供几种管理列表视图的方法,如用于处理点击事件的onListItemClick()
回调。(请注意,显示列表的首选方法是使用 RecyclerView,而非 ListView。在此情况下,您需在列表布局中创建包含 RecyclerView 的片段。如需了解具体操作方法,请参阅使用 RecyclerView 创建列表)PreferenceFragmentCompat
以列表形式显示
Preference
对象的层次结构。此类用于为您的应用创建设置屏幕。
添加界面
片段通常用作 Activity 界面的一部分,并且会将其自己的布局融入 Activity。
如要为片段提供布局,您必须实现 onCreateView()
回调方法,Android 系统会在片段需要绘制其布局时调用该方法。此方法的实现所返回的 View
必须是片段布局的根视图。
注意:如果您的片段是 ListFragment
的子类,则默认实现会从 onCreateView()
返回一个 ListView
,因此您无需实现它。
如要从 onCreateView()
返回布局,您可以通过 XML 中定义的布局资源来扩展布局。为帮助您执行此操作,onCreateView()
提供了一个 LayoutInflater
对象。
例如,以下 Fragment
子类从 example_fragment.xml
文件加载布局:
KOTLIN
class ExampleFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View {
// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.example_f