基本概念
Fragment,简称碎片,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。
Fragment的优点
- 模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
- 可重用(Reusability):多个Activity可以重用一个Fragment。
- 可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。
Fragment生命周期
Fragment的生命周期和Activity类似,但比Activity的生命周期复杂一些,基本的生命周期方法如下图:
- onAttach():Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。
- onCreate():Fragment被创建时调用。
- onCreateView():创建Fragment的布局。
- onActivityCreated():当Activity完成onCreate()时调用。
- onStart():当Fragment可见时调用。
- onResume():当Fragment可见且可交互时调用。
- onPause():当Fragment不可交互但可见时调用。
- onStop():当Fragment不可见时调用。
- onDestroyView():当Fragment的UI从视图结构中移除时调用。
- onDestroy():销毁Fragment时调用。
- onDetach():当Fragment和Activity解除关联时调用。
上面的方法中,只有onCreateView()在重写时不用写super方法,其他都需要。
Fragment使用
静态用法
- 继承Fragment,重写onCreateView决定Fragemnt的布局
- 在Activity中声明此Fragment,就当和普通的View一样
动态用法
- 获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。
- 开启一个事务,通过调用beginTransaction方法开启。
- 向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例。
- 提交事务,调用commit方法提交。
使用 FragmentManager 执行的操作包括:
-
通过 findFragmentById()(对于在 Activity 布局中提供 UI 的片段)或
findFragmentByTag()(对于提供或不提供 UI 的片段)获取 Activity 中存在的片段 -
通过 popBackStack()将片段从返回栈中弹出
-
通过 addOnBackStackChangedListener() 注册一个侦听返回栈变化的侦听器
-
也可以使用 FragmentManager 打开一个 FragmentTransaction,通过它来执行某些事务,如添加和删除片段。
FragmentTransaction的一些基本方法,下面给出调用这些方法时,Fragment生命周期的变化:
- add(): onAttach()->…->onResume()。
- remove(): onPause()->…->onDetach()。
- replace(): 相当于旧Fragment调用remove(),新Fragment调用add()。
- show(): 不调用任何生命周期方法,调用该方法的前提是要显示的 Fragment已经被添加到容器,只是纯粹把Fragment
UI的setVisibility为true。 - hide(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment
UI的setVisibility为false。 - detach():
onPause()->onStop()->onDestroyView()。UI从布局中移除,但是仍然被FragmentManager管理。 - attach(): onCreateView()->onStart()->onResume()。
注:
-
如果我们使用了support库的Fragment,就需要使用getSupportFragmentManager()获取FragmentManager。
-
add()是对Fragment众多操作中的一种,还有remove(), replace()等,第一个参数是根容器的id(FrameLayout的id),第二个参数是Fragment对象。
-
在一次事务中,可以做多个操作,比如同时做add().remove().replace()。
-
commit()操作是异步的,内部通过mManager.enqueueAction()加入处理队列。对应的同步方法为commitNow(),commit()内部会有checkStateLoss()操作,如果开发人员使用不当(比如commit()操作在onSaveInstanceState()之后),可能会抛出异常,而commitAllowingStateLoss()方法则是不会抛出异常版本的commit()方法,但是尽量使用commit(),而不要使用commitAllowingStateLoss()。
-
addToBackStack(“fname”)是可选的。FragmentManager拥有回退栈(BackStack),类似于Activity的任务栈,如果添加了该语句,就把该事务加入回退栈,当用户点击返回按钮,会回退该事务(回退指的是如果事务是add(frag1),那么回退操作就是remove(frag1));如果没添加该语句,用户点击返回按钮会直接销毁Activity。
-
Fragment有一个常见的问题,即Fragment重叠问题,这是由于Fragment被系统杀掉,并重新初始化时再次将fragment加入activity,因此通过在外围加if语句能判断此时是否是被系统杀掉并重新初始化的情况。