概述
一个Fragment代表着Activity中一种行为或者Activity用户界面中的一部分。我们可以将多个Fragment组合在一个Activity中,组成一个多窗格(multi-pane)布局;同样我们也可以在多个Activity中重复使用某个Fragment。我们可以将Fragment当作一个Activity中的小模块(它有它自己的生命周期,自己的事件处理机制),在Activity运行过程中,我们可以动态地添加或者移除这个模块。
Fragment在使用时,必须被嵌套在一个Activity中,我们可以称这个Activity为Fragment的“宿主Activity”,宿主Activity的生命周期直接影响到其中Fragment的生命周期。比如说:当宿主Activity进入暂停状态,其中所有的Fragment也会进入暂停状态,如果宿主Activity被销毁,其中包含的Fragment也会被销毁。然而,当宿主Activity正在运行,即处于resumed状态,我们可以独立地去操控某个Fragment,比如添加或者移除它。当我们执行一个Fragment事务的时候,我们可以将Fragment对象加入到宿主Activity管理的后台堆栈中,这个后台堆栈的每一个条目都是一次Fragment的事务记录。这个后台堆栈的作用是按下回退键时扭转Fragment事务的发生,即向后导航。
当我们将Fragment作为Activity的Layout布局的一部分加入到Activity中时,它会寄居在一个宿主Activity的View结构中的某个ViewGroup下,而且这个Fragment有自己的View布局。我们可以直接通过在Activity布局文件中使用<fragment>元素标签来声明插入Fragment到Activity中或者在代码中将它加入到一个ViewGroup下(所以,如果调用FragmentTransaction的add()方法,必须指定containerViewId,否则不会显示)。然而,Fragment并不需要一定作为Activity布局的一部分,我们有时可以使用一个没有UI且不可见的Fragment作为Activity的一个工人去帮Activity做一些事情。
Fragment是在Android 3.0(API 11)时提出来的,主要是用来让大屏设备(如:平板设备)的UI设计更加灵活和动态化。由于平板设备的屏幕空间远大于手持设备的屏幕空间,所以平板设备有更大的空间来组合控件和替换控件。Fragment不需要你去管理那些View结构的复杂变化 。通过将Activity的布局分割到Fragment中,我们可以在Activity的运行过程中,动态改变其UI并且将这种改变保存到Activity管理的一个栈中。
比如说:我们的应用中有一个文章列表和文章详情页面,由于平板设备空间大,列表Fragment和详情Fragment可以放在同一个页面中,而在手持设备上,则分为两个Activity作展示。如下图:
1. 创建一个Fragment
创建一个Fragment必须继承自Fragment类(或者它的某个子类,如果是API < 11的低版本,则继承V4包下的Fragment类)。Fragment的有些代码和Activity的看起来有点像。它包含了一些和Activity相似的回调方法,如:onCreate()
, onStart()
, onPause()
和onStop()
。实际上,当你改变现有App结构去使用Fragment的时候,你甚至会发现,你只要将Activity的回调方法中的代码移动到Fragment中对应的回调方法中就行了。一般来说,创建的Fragment中,我们需要实现下面三个生命周期方法:
【1】onCreate()
这个回调方法在系统创建Fragment的时候被调用,一般在这个方法中去初始化一些组件。
这个回调方法在Fragment第一次绘制自己的用户界面时被调用。为了绘制UI界面,这个方法必须返回一个View
对象,作为Fragment的布局结构的根布局,如果你不希望Fragment有UI界面,而只是单纯地帮Activity做一些事,你可以返回null。
【3】onPause()
这个回调方法会在用户离开这个Fragment页面时被调用(虽然这个时候Fragment并没有被销毁)。
其它还有很多有关Fragment的生命周期方法会在后面的小节中学习。
下面是几个Fragment的常用子类,我们有时候会选择继承它们,而不是去继承Fragment:
它展示的是一个悬浮的对话框。在Activity中使用这个类去创建一个对话框,替代之前的对话框。因为你可以将Fragment加入Activity管理的栈中,当用户点击返回按钮,可以让Fragment消失掉。
【2】ListFragment
它就像