Fragment简介

创建方式

静态创建

静态创建
首先我们需要创建一个xml文件,然后创建与之对应的java文件,通过onCreatView()的返回方法进行关联,最后我们需要在Activity中进行配置相关参数即在Activity的xml文件中放上fragment的位置。
<fragment
        android:name="xxx.BlankFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
</fragment>

动态创建

动态创建
	1.创建待添加的fragment实例。
	2.获取FragmentManager,在Activity中可以直接通过调用 getSupportFragmentManager()方法得到。
	3.开启一个事务,通过调用beginTransaction()方法开启。
	4.向容器内添加或替换fragment,一般使用repalce()方法实现,需要传入容器的id和待添加的fragment实例。
	5.提交事务,调用commit()方法来完成

Fragment和Activity的生命周期

动态加载时,ActivityonCreate()调用完,才开始加载fragment并调用其生命周期方法,所以在第一个生命周期方法onAttach()中便能获取Activity以及Activity的布局的组件。

静态加载时,ActivityonCreate()调用过程中,fragment也在加载,所以fragment无法获取到Activity的布局中的组件,但为什么能获取到Activity呢?原来在fragment调用onAttach()之前其实还调用了一个方法onInflate(),该方法被调用时fragment已经是和Activity相互结合了,所以可以获取到对方,但是ActivityonCreate()调用还未完成,故无法获取Activity的组件。ActivityonCreate()调用完成时,fragment会调用onActivityCreated()生命周期方法,因此在这儿开始便能获取到Activity的布局的组件。

Activity向Fragment传值

// Activity向Fragment传值,要传的值放到bundle对象里;Activity中创建该Fragment的对象fragment,通过调用setArguments()传递到fragment中;
在该Fragment中通过调用getArguments()得到bundle对象,就能得到里面的值。

ragment向Activity传值

1、第一种:
在Activity中调用getFragmentManager()得到fragmentManager,,调用findFragmentByTag(tag)或者通过findFragmentById(id),例如:
FragmentManager fragmentManager = getFragmentManager()Fragment fragment = fragmentManager.findFragmentByTag(tag)2、第二种:
通过回调的方式,定义一个接口(可以在Fragment类中定义),接口中有一个空的方法,在fragment中需要的时候调用接口的方法,值可以作为参数放在这个方法中,然后让Activity实现这个接口,必然会重写这个方法,这样值就传到了Activity

Fragment与Fragment之间是如何传值的

// Fragment与Fragment之间是如何传值的
1、通过findFragmentByTag得到另一个的Fragment的对象,这样就可以调用另一个的方法了;
2、通过接口回调的方式;
3、通过setArguments,getArguments的方式

Fragment和Adapter对比

FragmnetPageAdapter在每次切换页面时,只是将Fragment进行分离,适合页面较少的Fragment使用以保存一些内存,对系统内存不会多大影响


FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存

懒加载

// 懒加载
我们经常在使用fragment时,常常会结合着viewpager使用,那么我们就会遇到一个问题,就是初始化fragment的时候,会连同我们写的网络请求一起执行,这样非常消耗性能,最理想的方式是,只有用户点开或滑动到当前fragment时,才进行请求网络的操作。因此,我们就产生了懒加载这样一个说法。

Viewpager配合fragment使用,默认加载前两个fragment。很容易造成网络丢包、阻塞等问题。

在Fragment中有一个setUserVisibleHint这个方法,而且这个方法是优于onCreate()方法的,它会通过isVisibleToUser告诉我们当前Fragment我们是否可见,我们可以在可见的时候再进行网络加载。

从log上看setUserVisibleHint()的调用早于onCreateView,所以如果在setUserVisibleHint()要实现懒加载的话,就必须要确保View以及其他变量都已经初始化结束,避免空指针。

使用步骤:
申明一个变量isPrepare=false,isVisible=false,标明当前页面是否被创建了
在onViewCreated周期内设置isPrepare=true
在setUserVisibleHint(boolean isVisible)判断是否显示,设置isVisible=true
判断isPrepare和isVisible,都为true开始加载数据,然后恢复isPrepare和isVisible为false,防止重复加载。

Fragment家族常用API

.add()

.add()Activity中添加一个Fragment,这种方式切换fragment不会让fragment重新刷新,只会调用onHiddenChanged(boolean isHidden)

.remove()

.remove()Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁

.replace()

.replace()
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体,这种方式会使fragment重新刷新,因为add方式是将fragment隐藏了而不是销毁再创建,replace方式每次都是重新创建

.hide()

.hide()
当你的fragment数量固定很少时隐藏当前的Fragment,仅仅是设为不可见,并不会销毁,多的时候可能出现OOM异常

.show()

.show()
显示之前隐藏的Fragment

.commit()/.commitAllowingStateLoss()

.commit()/.commitAllowingStateLoss()
两者都可以提交fragment的操作,唯一的不同是第二种方法,允许丢失一些界面的状态和信息,几乎所有的开发者都遇到过这样的错误:无法在activity调用了onSaveInstanceState之后再执行commit(),这种异常时可以理解的,界面被系统回收(界面已经不存在),为了在下次打开的时候恢复原来的样子,系统为我们保存界面的所有状态,这个时候我们再去修改界面理论上肯定是不允许的,所以为了避免这种异常,要使用第二种方法

猜你喜欢

转载自blog.csdn.net/Mr_Gaojinchao/article/details/128794148