Fragment简称碎片,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。本文将从Fragment的定义、优点、生命周期以及基本使用这个几个方面来了解fragment的基础知识点。
一、Fragment的定义
frgment的官方定义:
Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running.
Fragment是activity的界面中的一部分或一种行为。你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一个Fragment。你可以把Fragment认为模块化的一段activity,它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除。
从Fragment的定义中我们知道Fragment有以下特点:
1.Fragment依赖Activity,不能独立存在,一个Activity中可以有多个fragment。
2.Fragment拥有自己的生命周期,可以在Activity内部被添加或者删除。
3.Fragment的生命周期只接受所在的Activity影响(Activity暂停,其Fragment也会暂停)。
4.Fragment的可重用:多个Activity可以重用一个Fragment。
二、Fragment的优点
1.模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
2.可重用(Reusability):多个Activity可以重用一个Fragment。
3.可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,用户体验更好。
三、Fragment的生命周期
1.官方生命周期图
生命周期各个方法解释如下:
- 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方法,其他都需要。
2.Fragment生命周期方法调用场景
onAttach() | Fragment和Activity建立关联时调用(获取Activity传递的值) |
onCreateView() | 为Fragment创建View(加载布局)时调用 |
onActivityCreated() | Activity的onCreate()方法执行完毕后调用 |
onDestoryView() | Fragment的布局被移除时调用 |
onDetach() | Fragment和Activity解除关联的时候调用 |
3.Fragment生命周期场景
场景 | 生命周期调用顺序 |
Fragment被创建 | onAttach()->onCreate()->onCreateView()->onActivityCreated() |
Fragment可见 | onStart()->onResume() |
Fragment进入后台 | onPause()->onStop() |
Fragment被销毁/退出应用 | onPause()->onStop()->onDestoryView()->onDestory()->onDetach() |
屏幕灭掉/回到桌面 | onPause()->onSaveInstanceState()->onStop() |
屏幕解锁/回到应用 | onStart()->onResume() |
切换到其他Fragment | onPause()->onStop()->onDestoryView() |
切换回本身Fragment | onCreateView()->onActivityCreated()->onStart()->onResume() |
4.Fragment和Activity生命周期对比图
其中,创建流程中,先执行Activity生命周期回调,再执行Fragment方法;而销毁流程中,先执行Fragment生命周期回调,再执行Activity方法。
四、Fragment的使用
1.静态添加
这种方法是使用Fragment的最简单的一种方式了,我们只需要声明一个类继承自Fragment实现其onCreateView方法,并将fragment声明在Activity的xml里即可。我们来看代码:
Fragment1.java:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
}
fragment1.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Fragment1" />
</RelativeLayout>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/fragmenta"
android:name="com.hbq.fragment.Fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这样我们就将Fragment1作为一个控件显示出来了,十分简单,只是需要注意fragment控件一定要加id属性即可,否则会崩溃。但是将Fragment作为一个控件来使用这种做法并不能发挥Fragment的优势,不值得提倡。
2.动态添加
在代码中通过FragmentManager获取FragmentTransaction来进行Fragment的动态添加,这种使用才是我们最常用的方式。接下来看代码:
MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragment1 = new Fragment1();
getFragmentManager().beginTransaction()
.replace(R.id.main_container, fragment1).commit();
getFragmentManager().beginTransaction().show(fragment1);
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这里我们在Activity中获取FragmentManager然后再进一步获取到FragmentTransaction对象将我们new出来的Fragment1 add到FrameLayout中。效果图跟上面第一种实现方式一致我就不贴图了。
这种动态加载Fragment的方式十分灵活,可以让我们在代码当中动态的决定加载哪些Fragment显示出来。这里我们需要重点关注的是FragmentTransaction对象。除了例子当中使用的add操作以外,它还有replace,hide,show,remove等操作,下面就对这几种方法一一进行解释。
1)add(int containerViewId, Fragment fragment)
这个方法是将fragmen添加到我们指定id的layout中.
2)hide(Fragment fragment)和show(Fragment fragment)
隐藏或者显示指定的fragment,类似于我们在View中经常使用的setVisibly方法,需要注意的是,这里的hide和show仅仅只是让fragment显示和隐藏,不会对fragment进行销毁,甚至我们在hide的时候fragment的onPause方法都没有被调用。
3)remove(Fragment fragment)
会将fragment移除,如果被移除的Fragment没有添加到回退栈,该Fragment会同时被销毁。
4)replace(int containerViewId, Fragment fragment)
replace方法是用来进行替换的,实际上也就是对指定的layout id先remove掉其fragment,然后再add上去我们指定的fragment的一种组合操作。
5)detach()
会将view从UI中移除,和remove()不同,此时fragment并没有与Activity断绝关系,所以生命周期的onDestroy方法和onDetach方法并没有被调用
6)attach()
重建view视图,附加到UI上并显示,如果调用完detach方法后再来调用该方法的话不会去走onAttach和onCreate方法。
需要注意的是,我们在进行了上述的各种操作以后一定要调用commit方法提交事务才能生效。
以上就是Fragment最基础的一些知识点,如有不当之处,欢迎指正。