Fragment(碎片),被称为 Andorid 第五大组件,也是继 Activity、Service、BroadcastReceiver、ContentProvider 四大组件之后有一个非常重要的组件,今天我们就来学习一下碎片 Fragment
一、概述
Fragment 表示 Activity 中的行为或用户界面部分,你可以将多个碎片组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个碎片,你也可以将碎片视为 Activity 的模块化组成部分,它具有自己的生命周期,能够接受自己的输入事件,并且可以在 Activity 运行时添加或移除碎片,
碎片必须始终嵌入在 Activity 中,其生命周期直接受到宿主 Activity 生命周期的影响,例如,当 Activity 暂停时,其中所有的片段也会暂停,当 Activity 被销毁时,所有片段也会被销毁,不过,当 Activity 正在运行(处于已恢复生命周期状态)时,你可以独立操纵每个碎片,如添加或删除它们,当你执行此类碎片事务时,你也可以将其添加到由 Activity 管理的返回栈(Activity 中的每个返回栈条目都是一条已发生碎片事务的记录),返回栈让用户可以通过按返回按钮撤销碎片事务
二、设计原理
Android 在 Android 3.0 (API 级别 11)中引入了碎片,主要是为了给大屏幕(如平板电脑)上更加动态的和灵活的 UI 设计提供支持,由于平板电脑的屏幕比手机屏幕大太多,因此可用于组合和交换 UI 组件的空间更大,利用碎片实现此类设计时,你无需管理对视图层次结构的复杂更改,通过将 Activity 布局分成碎片,你可以在运行时修改 Activity 的外观,并在由 Activity 管理的返回栈中保留这些更改
例如,新闻应用可以使用一个碎片在左侧显示文章列表,使用另一个碎片在右侧显示文章(这样两个碎片并排显示在一个 Activity 中)每个碎片都具有自己的一套生命周期回调方法,并且各自处理自己的用户输入事件,因此用户不需要使用一个 Activity 来选择文章,然后使用另一个 Activity 来阅读文章,而是可以在同一个 Activity 内选择文章进行阅读,如下图所示:
你应该将每个碎片都设计为可重复使用的模块化 Activity 组件,也就是所,由于每个碎片都会通过各自的生命周期方法回调来定义其自己的布局和行为,你可以将一个碎片加入多个 Activity,因此我们的应用应该采用可复用式设计,避免从某个碎片直接操纵另一个碎片,这个特别重要,因为模块化碎片让您可以通过更改碎片的组合方式来适应不同屏幕的尺寸,在设计可同时支持平板电脑和应用时,我们可以在不同的布局配置中复用我们的碎片,以根据可用的屏幕空间优化用户体验,例如,在手机上,如果不能再同一个 Activity 内放多个放多个碎片 Fragment,可能必须利用单独碎片来实现单窗格 UI
三、如何创建 Fragment
1)静态创建 Fragment
直接把 Fragment 当作一个普通的控件,在 Activity 的布局文件中声明,这里我们写一个简单的实例来演绎,在一个活动当中添加两个 Fragment
新建一个 ContentFragment 布局文件,fragment_content.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">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Content"
android:background="#059df7"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
然后我们再新建一个底部 BottomFragment 布局文件,fragment_bottom.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">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#686e68"
android:gravity="center"
android:text="Button"
android:textAllCaps="false"
android:textColor="#faf4f4"
android:textSize="20sp" />
</LinearLayout>
上面的两个布局都非常简单,我们就不在赘述,接着新建一个 ContentFragment 类并让它继承 Fragment
注意这里会有两个不同的包下的 Fragment 供我们选择,一个是系统内置的 andorid.app.Fragment,一个是 support - v4 库中的android.support.v4.app.Fragment,这里强烈建议大家使用 support - v4 库中的 Fragment ,因为它可以让 Fragment 在所有 Android系统版本中保持功能一致性,比如说 Fragment 中嵌套使用 Fragment,这个功能在 Android 4.2 系统中才开始支持,如果你使用的是系统内置的 Fragment,那么如果是 4.2 之前的设备运行你的程序就会崩溃,而使用 support - v4 库的 Fragment 就不会出现这个问题,另外我们并不需要在 build.gradle 中添加,因为 build.gradle 文件中已经添加了 appcompat - v7 库的依赖,而这个库会将 support - v4 库也一起引入进来
现在我们来编写 ContentFragment 中 的代码,如下:
public class ContentFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
return view;
}
}
这里仅仅重写了 Fragment 的 onCreateView() 方法,然后在这个方法中通过 LayoutInflater 的 inflate() 方法将我们刚才定义好的fragment_content 布局加载进来,接着我们用同样的方法新建 BottomFragment,代码如下:
public class BottomFragment extends Fragment {
@Nullable
@Override
publ