这是我参与「第四届青训营」笔记创作的第 12 天
此篇笔记是 Android 基础 —— 5、碎片Fragment (一) 碎片的静态注册
本篇笔记分为 2 部分
- 碎片的静态注册
- 碎片在静态注册时的生命周期
五、Fragment
本篇笔记将介绍 Fragment 碎片的概念及其用法
包括:通过静态注册方式使用碎片、通过动态注册方式使用碎片(需要配合碎片适配器 FragmentPagerAdapter ),并分析两种注册方式的碎片生命周期,最后结合实战演示了如何使用碎片改进启动引导页。
碎片的静态注册
碎片 Fragment 是个特别的存在,它有点像报纸上的专栏,看起来只占据页面的一小块区域,但是这一区域有自己的生命周期,可以自行其是,仿佛独立王国;并且该区域只占据空间不扰乱业务,添加之后不影响宿主页面的其他区域,去除之后也不影响宿主页面的其他区域。
每个碎片都有对应的 XML 布局文件,依据其使用方式可分为静态注册与动态注册两类。
静态注册指的是在 XML 文件中直接放置 fragment 节点,类似于一个普通控件,可被多个布局文件同时引用。静态注册一般用于某个通用的页面部件(如 Logo 条、广告条等),每个活动页面均可直接引用该部件。
下面是碎片页对应的 XML 文件内容,看起来跟列表项与网格项的布局文件差不多。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#bbffbb"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_adv"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center"
android:text="广告图片"
android:textColor="#000000"
android:textSize="17sp" />
<ImageView
android:id="@+id/iv_adv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4"
android:scaleType="fitCenter"
android:src="@drawable/test" />
</LinearLayout>
下面是与上述 XML 布局对应的碎片代码,除了继承自 Fragment 与入口方法 onCreateView 两点,其他地方类似活动页面代码。
public class StaticFragment extends Fragment {
private static final String TAG = "jzh";
// 把碎片贴到页面上
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Log.d(TAG, "Fragment onAttach");
}
// 页面创建
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "Fragment onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "Fragment onCreateView");
return inflater.inflate(R.layout.fragment_static, container, false);
}
若想在活动页面的 XML 文件中引用上面定义的 StaticFragment ,可以直接添加一个 fragment 节点,但需注意下列两点:
- fragment 节点必须指定 id 属性,否则 App 运行会报错。
- fragment 节点必须通过name属性指定碎片类的完整路径。
下面是在布局文件中引用碎片的 XML 例子。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/fragment_static"
android:name="com.example.myadvancedcontrols.fragment.StaticFragment"
android:layout_width="match_parent"
android:layout_height="60dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="这里是每个页面的具体内容"
android:textColor="#000000"
android:textSize="17sp" />
</LinearLayout>
运行测试 App ,可见此时碎片区域仿佛一个视图,其内部控件同样可以接收点击事件。
碎片在静态注册时的生命周期
另外,介绍一下碎片在静态注册时的生命周期,像活动的基本生命周期方法 onCreate 、 onStart 、 onResume 、onPause 、onStop 、onDestroy ,碎片同样也有,而且还多出了下面5个生命周期方法。
- onAttach :与活动页面结合。
- onCreateView :创建碎片视图。
- onActivityCreated :在活动页面创建完毕后调用。
- onDestroyView :回收碎片视图。
- onDetach :与活动页面分离。
至于这些周期方法的先后调用顺序,观察日志最简单明了。下面是打开活动页面时的日志信息,此时碎片的 onCreate 方法先于活动的 onCreate 方法,而碎片的 onStart 与 onResume 均在活动的同名方法之后。
12:26:11.506:D/StaticFragment:onAttach
12:26:11.506:D/StaticFragment:onCreate
12:26:11.530:D/StaticFragment:onCreateView
12:26:11.530:D/FragmentStaticActivity:onCreate
12:26:11.530:D/StaticFragment:onActivityCreated
12:26:11.530:D/FragmentStaticActivity:onStart
12:26:11.530:D/StaticFragment:onStart
12:26:11.530:D/FragmentStaticActivity:onResume
12:26:11.530:D/StaticFragment:onResume
下面是退出活动页面时的日志信息,此时碎片的 onPause 、onStop 、onDestroy 都在活动的同名方法之前。
12:26:36.586:D/StaticFragment:onPause
12:26:36.586:D/FragmentStaticActivity:onPause
12:26:36.990:D/StaticFragment:onStop
12:26:36.990:D/FragmentStaticActivity:onStop
12:26:36.990:D/StaticFragment:onDestroyView
12:26:36.990:D/StaticFragment:onDestroy
12:26:36.990:D/StaticFragment:onDetach
12:26:36.990:D/FragmentStaticActivity:onDestroy
总结一下,在静态注册时,除了碎片的创建操作在页面创建之前,其他操作没有僭越页面范围。就像老 实本分的下级,上级开腔后才能说话,上级要做总结性发言前赶紧闭嘴。