第7章 UI fragment 与 fragment 管理器
另 一 个 重 要 的 支 持 库 类 是 FragmentActivity ( android.support.v4.app.Fragment- Activity)。activity知道如何管理fragment,因此fragment的使用需要activity的支持。在Honeycomb 及后续的Android版本中,Activity的所有子类都知道如何管理fragment。而这之前版本的 Activity则完全不了解fragment,Activity的子类自然也就无从知晓。为兼容较低版本的设备, 可继承FragmentActivity类。FragmentActivity是Activity的子类,具有新系统版本 Activity类管理fragment的能力,即便是在较早版本的Android设备上也可对fragment进行管理。
fragment生命周期与activity生命周期的一个关键区别就在于,fragment的生命周期方法是由托管activity而不是操作系统调用的。操作系统无从知晓activity用来管理视图的fragment。fragment 的使用是activity自己内部的事情。
Fragment类中的onCreateView方法:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime, container, false);
return view;
}
View view = inflater.inflate(R.layout.fragment_crime, container, false);别忘了第三个参数。
在 onCreateView(...) 方法中 , fragment 的 视 图 是 直 接 通 过 调 用 LayoutInflater.inflate(...)方法并传入布局的资源ID生成的。第二个参数是视图的父视图,通常我们需要父 视图来正确配置组件。第三个参数告知布局生成器是否将生成的视图添加给父视图。这里,我们 传入了false参数,因为我们将通过activity代码的方式添加视图。
7.6.1 fragment事务
public class CrimeActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime);
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.fragmentContainer);//使用容器资源ID识别fragment
if (fragment == null) {
fragment = new CrimeFragment();
fragmentManager.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
}
}
}
因为使用了支持库及FragmentActivity类,因此这里调用的方法是getSupportFragment- Manager()。如果不考虑Honeycomb以前版本的兼容性问题,可直接继承Activity类并调用 getFragmentManager()方法。
容器视图资源ID主要有两点作用:
- 告知FragmentManagerfragment视图应该出现在activity视图的什么地方;
- 是FragmentManager队列中fragment的唯一标识符。 如需从FragmentManager中获取CrimeFragment,即可使用容器视图资源ID。
FragmentManager使用FrameLayout组件的资源ID去识别CrimeFragment,这看上去可能有点 怪。但实际上,使用容器视图资源ID去识别UI fragment已被内置在FragmentManager的使用机制中。
首先,使用R.id.fragmentContainer的容器视图资源ID,向FragmentManager请求获取 fragment。如要获取的fragment在队列中已经存在,FragmentManager随即会将之返还。
为什么队列中已经有fragment存在了呢?CrimeActivity因设备旋转或回收内存被销毁后重建时, CrimeActivity.onCreate(...)方法会响应activity的重建而被调用。activity被销毁时, 它的FragmentManager会将fragment队列保存下来。这样,activity重建时,新的FragmentManager 会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。
在activity处于停止、暂停或运行状态下时,添加fragment会发生什么呢?此种情况下, FragmentManager立即驱使fragment快速跟上activity的步伐,直到与activity的最新状态保持同步。例如,向处于运行状态的activity中添加fragment时,以下fragment生命周期方法会被依次调用: onAttach(Activity)、onCreate(Bundle)、onCreateView(...)、onActivityCreated(Bundle)、 onStart(),以及onResume()方法。