一、Fragment介绍
Fragment是在Android 3.0 (API level 11)开始引入的,它能让你的app在现有基础上性能大幅度提高,并且占用内存降低,同样的界面Activity占用内存比Fragment要多,响应速度Fragment比Activty在中低端手机上快了很多,甚至能达到好几倍,"单Activity + 多Fragment架构"和"多模块Activity + 多Fragment架构"应运而生!
Fragment导包时有两个选择:
-
android.app.Fragment
-
android.support.v4.app.Fragment
后者兼容android3.0以下的版本。两个版本都可以使用,但是要注意相关函数引用要保持一致,更不要混用。
本文涉及源码:https://github.com/gitEkko/MyApplication.git
二、生命周期
onAttach() | 关联到Activity的时候调用。如果,需要使用Activity的引用或者使用Activity作为其他操作的上下文,将在此回调方法中实现 |
onCreate() | 系统创建Fragment的时候回调 |
onCreateView() | 当第一次绘制Fragment的UI时系统调用这个方法,该方法将返回一个View,如果Fragment不提供UI也可以返回null。 |
onActivityCreated() | 当Activity中的onCreate方法执行完后调用。可以在这个函数里面做和Activity UI交互的操作(因为Activity的onCreate()函数之后Activity的UI已经准备好了,可以UI交互)。 |
onStart() | 启动Fragment的时候回调,这个时候Fragment可见 |
onResume() | Fragment变为活动状态获取焦点的时候是回调,这个时候Fragment已经完全展示在前台,并且可以和用户交互 |
onPause() | Fragemnt变成非活动状态失去焦点的时候调用,注意这个时候Fragment还是可见的,只是不能和用户交互了而已 |
onStop() | Fragment变成不可见的时候调用。这个时候Fragment还是活着的,只是可能被加入到了Fragment的回退栈中 |
onDestroyView() | Fragment中的布局被移除的时候调用 |
onDestroy() | Fragment被销毁的时候调用 |
onDetach() | Fragment和Activity解除关联的时候调用个 |
此外,注意以下周期函数:
- onViewCreated(): 是在onCreateView()函数之后执行,我们通常在onViewCreated()函数里面findViewById。
- setUserVisibleHint():当前页面是否可见(一般ViewPager+Fragemnt配合使用会用到,懒(延时)加载的时候这个函数有大用处),因为ViewPager+Fragemnt的时候是会同时去加载前后多个Fragment的,这个时候就有些Fragment是可见的一些Fragment是不可见的。有一点要注意setUserVisibleHint()只在ViewPager+Fragment这情况下才会回调,其他静态加载和动态加载Fragment不会被调用到。
- onHiddenChanged():hide()、show()切换Fragment显示的时候,Fragment只会回调onHiddenChanged()。Fragment在add()的时候不会回调onHiddenChanged()函数。还有,在ViewPager+Fragment使用的时候Fragment也不会回调onHiddenChanged()函数的。
极力推荐大神总结的博客,认真看一遍,自己打打Log,绝对能把Fragment生命周期安排的明明白白。https://blog.youkuaiyun.com/MeloDev/article/details/53406019#comments
三、具体使用
- 静态加载
- 动态加载
静态加载 :直接将Fragment当作一个控件,添加在布局文件中。
<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:name="com.xxx.app.FragmentTest.ExampleFragment"
android:id="@+id/content"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
动态加载:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (!navigateFragment.isAdded()) {
fragmentTransaction.add(R.id.fragment_content, navigateFragment, getString(R.string.tab_1));
} else {
fragmentTransaction.show(navigateFragment);
}
//fragmentTransaction.replace(R.id.fragment_content, navigateFragment, getString(R.string.tab_1));
fragmentTransaction.commit();
//fragmentTransaction.commitAllowingStateLoss();
根据上述代码,可以看出Fragment的动态使用用到了FragmentManager 。下面开始介绍FragmentManager :
Fragment常用的三个类:
- android.app.Fragment
- android.app.FragmentManager 用于在Activity中才做Fragment
- android.app.FragmentTransaction 保证一系列Fragment操作的原子性,事务相关。
对应v4包:
- android.support.v4.app.Fragment
- android.support.v4.app.FragmentManager
- android.support.v4.app.FragmentTransaction
获取 FragmentManager:getFragmentManager(); v4:getSupportFragmentManager()
FragmentManager fragmentManager = getSupportFragmentManager();//v4包
//FragmentManager fragmentManager = getFragmentManager();
开启FragmentTransaction事务:
FragmentTransaction transaction = fragmentManager.beginTransaction();
- transaction.add() :添加一个Fragment
- transaction.remove():移除一个Fragment,如果此Fragment没有加入到回退栈,其实例将会被销毁
- transaction.replace():使用另一个Fragment替换当前,作用等效于add+remove
- transaction.hide():隐藏当前的Fragment,仅仅是设为不可见,不会销毁实例
- transaction.show():将隐藏的fragment显示出来。
提交 FragmentTransaction事务:
transaction.commit();
//transaction.commitAllowingStateLoss();
注:commit方法要在Activity.onSaveInstance()之前调用,否则会出现Activity状态不一致:State loss 的问题。
在commit()方法之前,你可以调用addToBackStack(),把这个transaction加入back stack中去,这个back stack是由activity管理 的,当用户按返回键时,就会回到上一个fragment的状态。
你只能在activity存储它的状态(当用户要离开activity时)之前调用commit(),如果在存储状态之后调用commit(),将会抛出一个异常。这是因为当activity再次被恢复时commit之后的状态将丢失。如果丢失也没关系,那么使用commitAllowingStateLoss()方法。
四、通信方式
移步:[Android]Fragment与Activity之间的通信方案
五、Fragment+Tablayout+ViewPager+ BottomNavigationView
源码:https://github.com/gitEkko/MyApplication.git
先上Demo截图:
比较主流的布局方式,单Activity+多Fragment。上方利用Tablayout和ViewPager实现页面切换。下方利用 BottomNavigationView导航栏实现页面切换。第一页导航页添加Tablayout+ViewPager布局。
该Demo涉及:
- BottomNavigationView使用 <