第5章〓UI进阶 本章思维导图 本章目标  能够熟练使用Fragment动态设计UI界面;  能够熟练使用Menu和Toolbar组件;  能够熟练使用AdapterView、ListView和GridView;  掌握TabHost组件的使用。 5.1Fragment Android从3.0版本开始引入Fragment(碎片),允许将Activity拆分成多个完全独立封装的可重用的组件,每个组件拥有自己的生命周期和UI布局。使用Fragment为不同型号、尺寸、分辨率的设备提供统一的UI设计方案,Fragment最大的优点是让开发者更加灵活地根据屏幕大小(包括小屏幕的手机、大屏幕的平板电脑)来创建相应的UI界面。 以新闻列表为例,当针对小屏幕手机开发时,开发者通常需要编写两个Activity,分别是Activity A和Activity B,其中,Activity A用于显示所有的新闻列表,列表内容为新闻的标题; Activity B用于显示新闻的详细信息; 当用户单击某个新闻标题时,由Activity A启动Activity B,并显示该标题所对应的新闻内容,两个Activity界面如图51所示。 图51手机上显示新闻列表 当针对平板电脑开发时,使用Fragment A来显示标题列表,使用Fragment B来显示新闻的详细内容,将这两个Fragment在同一个Activity中并排显示; 当单击Fragment A中的新闻标题时,通过Fragment B来显示该标题对应的新闻内容,显示效果如图52所示。每个Fragment都有自己的生命周期和相应的响应事件,通过切换Fragment同样可以实现显示效果的切换。 图52平板电脑上显示新闻列表及内容 每个Fragment都是独立的模块,并与其所绑定的Activity紧密联系在一起,Fragment通常会被封装成可重用的模块。对于一个界面允许有多个UI模块的设备(如平板电脑等),Fragment拥有更好的适应性和动态构建UI的能力,在Activity中可以动态地添加、删除或更换Fragment。 由于Fragment具有独立的布局,能够进行事件响应,且具有自身的生命周期和行为,所以开发人员还可以在多个Activity中共用一个Fragment实例,即当程序运行在大屏设备时启动一个包含多个Fragment的Activity,当程序运行在小屏设备时启动一个包含少量Fragment的Activity。同样以新闻列表为例,对程序进行如下设置: 当检测到程序运行在大屏设备时,启动Activity A,并将标题列表和新闻内容所对应的两个Fragment都放在Activity A中; 当检测到程序运行在小屏设备时,依然启动Activity A,但此时Activity A中只包含一个标题列表Fragment,当用户单击某个新闻标题时,Activity A将启动Activity B,再通过Activity B加载新闻内容所对应的Fragment。 5.1.1使用Fragment 创建Fragment的过程与Activity类似,自定义的Fragment必须继承Fragment类或其子类。Fragment的继承体系如图53所示。 图53Fragment的继承体系 与Activity类似,同样需要实现Fragment中的回调方法,如onCreate()、onCreateView()、onStart()和onResume()等。 通常在创建Fragment时,需要实现以下三个方法。  onCreate(): 系统在创建Fragment对象时调用此方法,用于初始化相关的组件,例如,一些在暂停或者停止时依然需要保留的组件。  onCreateView(): 系统在第一次绘制Fragment对应的UI时调用此方法,该方法将返回一个View,如果Fragment未提供UI则返回null。当Fragment继承自ListFragment时,onCreateView()方法默认返回一个ListView。  onPause(): 当用户离开Fragment时首先调用此方法; 当用户无须返回时,可以通过该方法来保存相应的数据。 Fragment不能独立运行,必须嵌入Acitivity中使用,因此Fragment的生命周期与其所在的Activity密切相关。 将Fragment加载到Activity中主要有以下两种方式。  把Fragment添加到Activity的布局文件中。  在Activity的代码中动态添加Fragment。 在上述两种方式中,第一种方式虽然简单但灵活性不够。如果把Fragment添加到Activity的布局文件中,就会使得Fragment及其视图与Activity的视图绑定在一起,在Activity的生命周期中,无法灵活地切换Fragment视图。因此在实际开发过程中,多采用第二种方式。相对而言,第二种方式要比第一种方式复杂,但也是唯一一种可以在运行时控制Fragment的方式,可以动态地添加、删除或替换Fragment实例。 1. 创建Fragment 下述代码演示了Fragment的基本用法。屏幕分为左右两部分,通过单击屏幕左侧的按钮,在右侧动态地显示Fragment。其布局文件代码如下。 【案例51】fragment_main.xml