本系列的文章全部为学习摘要,不偏重各种细节展示,更多的是安卓体系重要节点的罗列,并适时加入少量自己的理解分析,以便能快速的回顾安卓体系结构和那些重要的技术点。
片段Fragment必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。 例如,当 Activity 暂停时,其中的所有片段也会暂停;当 Activity 被销毁时,所有片段也会被销毁。 不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您可以独立操纵每个片段,如添加或移除它们,即当Acty在onResume时,其内部Fragment并不一定调用对应的onResume方法。
应该将每个片段都设计为可重复使用的模块化 Activity 组件。也就是说,由于每个片段都会通过各自的生命周期回调来定义其自己的布局和行为,可以将一个片段加入多个 Activity,因此,应该采用可复用式设计,避免直接从某个片段直接操纵另一个片段。
创建片段
- 要想创建片段,您必须创建 Fragment 的子类(或已有其子类)。通常,您至少应实现以下生命周期方法:
-> onCreate()
系统会在创建片段时调用此方法。您应该在实现内初始化您想在片段暂停或停止后恢复时保留的必需片段组件。
-> onCreateView()
系统会在片段首次绘制其用户界面时调用此方法。 要想为您的片段绘制 UI,您从此方法中返回的 View 必须是片段布局的根视图。如果片段未提供 UI,您可以返回 null。
-> onPause()
系统将此方法作为用户离开片段的第一个信号(但并不总是意味着此片段会被销毁)进行调用。
添加用户界面
实现 onCreateView() 回调方法,Android 系统会在片段需要绘制其布局时调用该方法。对此方法的实现返回的 View 必须是片段布局的根视图。
例如:
public static class ExampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
inflate() 方法带有三个参数:
-> 您想要扩展的布局的资源 ID;
-> 将作为扩展布局父项的 ViewGroup。传递 container 对系统向扩展布局的根视图(由其所属的父视图指定)应用布局参数具有重要意义;
-> 布尔值。值若为 false,则inflate时仅让xml布局限定于container的布局参数;若传递 true 值,inflate时会使container.addview(xml布局),到最终,布局中创建一个多余的视图组。
向 Activity 添加片段
- 布局文件内声明片段
可通过findFragmentById(),找到,布局代码基本同view的一样,只是声明的时候使用< fragment >标签,name使用全限定名称。
- 在代码中声明
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
- 添加没有 UI 的片段
使用片段为 Activity 提供后台行为,而不显示额外 UI,添加方法–add(Fragment, String) (为片段提供一个唯一的字符串“标记”,而不是视图 ID)不会收到对 onCreateView() 的调用。从 Activity 中获取片段,则需要使用 findFragmentByTag()方法。
与 Activity 通信
Activity操作fragment,可以通过 findFragmentById() 或 findFragmentByTag()得到fragment的实例,进一步调用其方法。
fragment调用Activity方法,可以在fragment中定义一个接口,声明需要调用的方法,然后让Activity实现该方法,然后按如下代码:
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
...
生命周期
如需 Fragment 内的某个 Context 对象,可以调用 getActivity()。但要注意,请仅在片段附加到 Activity 时调用 getActivity()。如果片段尚未附加,或在其生命周期结束期间分离,则 getActivity() 将返回 null。
作者: 刘咸尚
不过,片段还有几个额外的生命周期回调,用于处理与 Activity 的唯一交互,以执行构建和销毁片段 UI 等操作。 这些额外的回调方法是:
onAttach()
在片段已与 Activity 关联时调用(Activity 传递到此方法内)。
onCreateView()
调用它可创建与片段关联的视图层次结构。
onActivityCreated()
在 Activity 的 onCreate() 方法已返回时调用。
onDestroyView()
在移除与片段关联的视图层次结构时调用。
onDetach()
在取消片段与 Activity 的关联时调用。
其它的用个图最具代表