android学习笔记之创建UI fragment(二)

创建UI fragment的步骤与创建activity的步骤相同:

  • 定义用户界面布局文件;
  • 创建fragment类并设置其视图为定义的布局;
  • 编写代码以实例化组件。

定义CrimeFragment 的布局
CrimeFragment视图用来显示包含在Crime类实例中的信息。


1. 实现fragment生命周期方法

CrimeFragment类是与模型及视图对象交互的控制器,用于显示特定crime的明细信息,并在 用户修改这些信息后立即进行更新。 在GeoQuiz应用中,activity通过其生命周期方法完成了大部分逻辑控制工作。而在 CriminalIntent应用中,这些工作是由fragment的生命周期方法完成的。
,fragment的视图并没有在Fragment.onCreate(Bundle)方法中生成。虽然我们在该方 法中配置了fragment实例,但创建和配置fragment视图是另一个Fragment生命周期方法完成的:

public View onCreateView(LayoutInflater inflater, ViewGroup container,     Bundle savedInstanceState) 

该方法实例化fragment视图的布局,然后将实例化的View返回给托管activity。 LayoutInflater及ViewGroup是实例化布局的必要参数。Bundle用来存储恢复数据,可供该方 法从保存状态下重建视图。 在CrimeFragment.java中,添加onCreateView(…)方法的实现代码,从fragment_crime.xml 布局中实例化并返回视图.


2. 在fragment中实例化组件
唯一的区别是,你调用了fragment视图的View.findViewById(int)方法。以前使 用的Activity.findViewById(int)方法十分便利,能够在后台自动调用View.findViewById (int)方法,而Fragment类没有对应的便利方法,因此必须手动调用。

fragment自己无法在屏幕上显示视图,怎么办?把CrimeFragment添加给CrimeActivity


3.向FragmentManager 添加 UI fragment
FragmentManager类负责管理fragment并将它们的视图添加到activity的视 图层级结构中。
这里写图片描述
FragmentManager类具体管理:

  • fragment队列;
  • fragment事务回退栈(稍后会学习)。
    要以代码的方式将fragment添加给activity,需要直接调用activity的FragmentManager。首先 是获取FragmentManager本身。

4. fragment事务
获取FragmentManager之后,再获取一个fragment交给它管理。

 Fragment fragment = fm.findFragmentById(R.id.fragment_container); 
 if (fragment == null) {   
    fm.beginTransaction()    
    .add(R.id.fragment_container,fragment)    
.commit();   
}

这段代码创建 并提交了一个fragment事务;fragment事务被用来添加、移除、附加、分离或替换fragment队列中的fragment。这是使用 fragment动态组装和重新组装用户界面的关键。FragmentManager管理着fragment事务回退栈。
add(…)方法是整个事务的核心:

  • 告诉FragmentManager,fragment视图应该出现在activity视图的什么位置;
  • 唯一标识FragmentManager队列中的fragment。

    FragmentManager使用FrameLayout组件的资源ID识别CrimeFragment,这看上去可能有点 怪。但实际上,使用容器视图资源ID识别UI fragment就是FragmentManager的一种内部实现机制。 如果要向activity添加多个fragment,通常就需要分别为每个fragment创建具有不同ID的不同容器。

为什么要获取的fragment可能有了呢?前面说过,设备旋转或回收内存时,Android系统会销 毁CrimeActivity,而后重建时,会调用CrimeActivity.onCreate(Bundle)方法。activity被 销毁时,它的FragmentManager会将fragment队列保存下来。这样,activity重建时,新的 FragmentManager会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。 当然,如果指定容器视图资源ID的fragment不存在,则fragment变量为空值。这时应该新建 CrimeFragment,并启动一个新的fragment事务,将新建fragment添加到队列中。


5.FragmentManager 与 fragment生命周期
这里写图片描述
activity的FragmentManager负责调用队列中fragment的生命周期方法。添加fragment供 FragmentManager管理时,onAttach(Context)、onCreate(Bundle)和onCreateView(…)方法 会被调用。
托管activity的onCreate(Bundle)方法执行后,onActivityCreated(Bundle)方法也会被 调用。因为是在CrimeActivity.onCreate(Bundle)方法中添加CrimeFragment,所以fragment 被添加后,该方法会被调用。
在activity处于运行状态时,添加fragment会发生什么呢?这种情况下,FragmentManager立 即驱赶fragment,调用一系列必要的生命周期方法,快速跟上activity的步伐(与activity的新状 态保持同步)。一旦追上,托管activity的FragmentManager就会边接收操作系统的调用指令,边调用其他生 命周期方法,让 fragment与activity的状态取得一致。


3. 采用fragment的应用架构
fragment是用来封装关键组件以方便复用。这里所说的关键组件,是针对应用的整个屏幕来 讲的。如果单屏就使用大量fragment,不仅应用代码充斥着fragment事务处理,模块的职责分工 也会不清晰。如果有很多零碎小组件要复用,比较好的架构设计是使用定制视图(使用View子类)。实践证明,
应用单屏多使用2~3个fragment。

使用 fragment的理由
这是实际开发中比较实用的模式,建议尽早适应。,从一开始就使用fragment更容易,既不用返工,也不会出现 理不清哪个部分使用了哪种视图控制风格这种事了。 因而,对于fragment,我们坚持AUF(Always Use Fragments)原则,即“总是使用fragment”。


深入学习:fragment与支持库
,为使用支持库版fragment,CriminalIntent项目引入了AppCompat库。然而,这个 库自身并没有实现fragment功能,它依赖support-v4库。所以,真正实现fragment功能的是 support-v4库。 。要使 用支持库版fragment,应用的activity必须继承FragmentActivity。


深入学习:为什么优先使用支持库版 fragment
理由是什么?我们认为,支持库版fragment使用方便。任何时候,只要想升级支持 库版fragment的话,只需要下载升级包,重新编译发布一个新版本应用就行了。Google每年会多 次更新支持库,并借此引入新特性、修复bug。要享受这些好处,升级应用的支持库版本就行了。非要挑毛病的话,那就是导入支持库包会占用额外空间。

当然,如果你有自己的想法,非要用操作系统内置版fragment,也可以。 要使用标准库里的fragment,需对项目做以下改动。

  • 弃用FragmentActivity类,改用标准库中的Activity类(android.app.Activity)。 它默认支持在API 11级或更高版本系统中使用fragment。
  • 弃用android.support.v4.app.Fragment类,改用android.app.Fragment类。
  • 弃用getSupportFragmentManager()方法,改用getFragmentManager()方法获取 FragmentManager。

猜你喜欢

转载自blog.csdn.net/qq_40104617/article/details/82709191