黄立明+江有福+陆雅男
摘要:以传统的方式实现多级选项列表,不仅构建困难,而且不利于管理,缺乏灵活性,这种情况在Android 3.0引入了Fragment技术之后得到改善。Fragment技术支持更加灵活的UI设计,增强了对平板和手机的兼容性,为多级选项列表的实现提供了一种全新的设计思路。本文完整地介绍Fragment的生命周期,并通过详细的实例制作过程体现其灵活和便于管理的特性。
关键词:安卓;碎片;用户界面;多级选项列表
中图分类号:G642 文献标志码:A 文章编号:1674-9324(2015)15-0153-04
0 引言
Fragment中文意思是碎片,用于在一个Activity中描述部分操作界面和相关的行为。使用Fragment分散整个Activity的布局,体现出了良好的模块化思维,提高了碎片的重用性。Fragment技术出现之前,多级选项列表的实现方式是先设置布局,再控制各级列表对应视图的展现或隐藏。这样做,更多关注的是视图层次的变化,但是根据线程安全的原则,在子线程中不能直接修改UI界面,难以实现灵活管理。虽然可以使用Handler消息机制解决灵活管理的问题,但是Handler机制比较烦琐,容易导致代码臃肿。然而使用Fragment,则不需要亲自管理视图层次的复杂变化,会在程序运行时修改Activity的外观。所以我们依据Fragment灵活的特性来实现多级选项列表,同时保持了良好的代码风格。
图1是Fragment和Activity生命周期的对比图。Fragment作为Activity的一部分,拥有一个与其相关的视图层次结构以及与Activity非常相似的生命周期。
1 Fragment初始化
Fragment并非Activity的子类,Fragment直接继承Object,而Activity直接继承ContextThemeWrapper。
2 Fragment的生命周期
2.1 onAttach()
当Fragment附加到Activity时,该回调方法会被调用。此方法中可以通过getActivity()方法获得附加的Activity,将Fragment附加到Activity前,可以使用setArguments()方法附加参数到一个Bundle对象(初始化参数包)。在Fragment的整个生命周期中,初始化参数包都可以用Fragment的getArguments()方法获得。
2.2 onCreate()
此回调发生在Activity需要获取Fragment的布局时。如果Fragment是恢复的,则该回调过程中可以获取传入的Bundle型对象包savedInstanceState,这个对象包保存了Fragment的上一状态数据,也可以在onCreateView()和onActivityCreated()中获取该对象包。这个过程中应当尽量避免可能阻塞主线程的操作,例如获取网络数据,登陆验证等。
2.3 onCreateView()
此回调发生在Fragment绘制界面并返回一个根视图时,如果不需要视图层次,可以返回null。该方法的声明中包含三个参数,分别是inflater,container,savedInstanceState。inflater参数可以调用inflate()方法动态加载一个xml布局文件来返回视图;container参数指定需要插入fragment布局的父容器;savedInstanceState参数不再赘述。
2.4 onActivityCreated()
此回调过程发生在Activity的onCreate()回调之后,可以存在需要依赖于Activity视图层次的代码,例如进行一些属性的设置。
2.5 其他
只有当Activity处于resumed状态时,Fragment的生命周期才得以独立运转,其他它时候是依赖于Activity的生命周期变化的。这种绑定Activity的时期包含了onStart()回调、onResume()回调、onPause()回调以及onStop()回调。因为我们不确定用户是否还会返回,在onPause()方法中通常做一些数据持久化的工作,再通过onSaveInstanceState()方法保存Fragment的状态值。
3 创建Fragment
创建Fragment首先需要创建扩展Fragment类的Java类,并重写其onCreateView()方法,在这个方法中按具体的方式创建碎片。
3.1 加载布局式
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
View v = inflater.inflate(R.layout.content,null);
}
该方式通过LayoutInflater类的对象inflater调用inflate()方法加载xml布局文件来创建Fragment。示例代码中加载的是content.xml布局文件。
3.2 Java代码式
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
//构建Fragment的java代码
}
该方式通过在onCreateView()方法中书写java代码来构建Fragment。
4 显示Fragment
在Activity中显示Fragment主要有两种方式,分别是静态载入xml布局方式和动态管理方式。第一种方式是对碎片进行布局,尽管这种方式已经够用,但是为了更好的实现运行时刻与屏幕上的碎片交互,还需引入动态管理的方式。
4.1 静态载入xml
该方式是通过在Activity的xml布局文件中定义一个或多个
4.2 动态管理
该方式需要借助Android系统控制碎片的工具FragmentManager来实现的。需要注意的是,xml布局中使用
实现步骤如下:
(1)先调用指定类的初始化函数实例化Fragment。
(2)再使用getFragmentManager()方法获取FragmentManager,并通过其提供的接口方法beginTransaction()返回一个FragmentTransaction的实例。
(3)然后设置Fragment的转场动画。
(4)再指定方式(replace、remove、add)和需要替换为碎片的视图容器(第一个参数)。
(5)最后提交事务。
对应代码如下图所示。
5 制作多级选项列表
使用安卓开发工具ADT设计应用程序时,首先需要编写应用程序主界面Activity的xml布局文件,然后其余的工作交由java过程设计代码来处理。通常编程人员在继承使用系统类的时候,会依照实际开发需求扩展需要的功能。此处我们需要扩展使用ListFragment,实现其中的onListItemClick()方法来响应用户的点击事件。
5.1 Activity的xml布局
5.2 一级列表
主要代码如图3所示。
代码分析:
一级列表类TitleFragment用于显示一级列表,是以静态形式首先被加载,所以不需要初始化,即不需要显式的构造函数。在Activity调用setContentView()方法设置视图时,Fragment通过xml文件中〈fragment〉标记映射对应的类。
第3~10行:在onCreate()方法中准备列表的数据;
第11~13行:在onCreate()方法中指定适配器;
第17行:在OnActivityCreated()方法中为列表设置适配器;
第22行:重写ListFragment的onListItemClick()方法,其中调用showDetails()方法;
第27~31行:在showDetails()方法中使用动态管理的方式显示二级列表视图。
实现效果如图4所示。
5.3 二级列表
5.3.1 主要代码如图5所示。
代码分析:
二级列表类DetailFragment1用于显示二级列表,因为二级列表需要根据一级列表的选中值来动态选择该列表所要显示的内容,所以需要显式的写出初始化函数。
第1~2行:显式的初始化函数newInstance()中实例化DetailFragment1_triage;
第3~6行:使用bundle包保存二级列表的状态,并返回DetailFragment1_triage类的对象df;
第11~13行:在onCreateView()方法中,为listview设置适配器;
第14行:给listview设定选择模式;
第16行:返回视图listview;
第23行:重写onListItemClick()方法中调用showDetails()方法;
第26~27行:在showDetails()方法中使用动态管理的方式显示三级列表。
实现效果如图6所示。
5.4 三级列表
三级列表类DetailFragment2的实现和二级列表类DetailFragment1的实现类似。
6 最终效果
7 总结
本文基于对Fragment生命周期的理解,挖掘了Fragment技术的使用范围,提供了一种新的基于Fragment技术实现多级选项列表的方法。
基于Fragment技术的应用程序设计体现了如下的几大特性。
(1)对Android手机和平板有良好的兼容性。
(2)Fragment对应用程序框架构建的支持,淘汰了陈旧的TabActivity和ActivityGroup。
(3)Fragment分散Activity的特性大大提升Fragment代码的重用性。
参考文献:
[1]王云林.Android应用中跨版本集成新特性的研究与实现[D].上海:东华大学计算机系,2013.
[2]史书明.Android应用中消息传递方法分析[J].电脑知识与技术,2014,10(13):2984-2986.
[3]李刚.疯狂Android讲义[M].北京:电子工业出版社,2013.
[4]王涛.安卓系统消息传递方法研究[J].安阳工学院学报,2014,13(4):61-63.
[5]Chris Haseman.Android应用开发[M].北京:人民邮电出版社,2013:172-178.