应该将每一个fragment设计为模块化和可复用化的activity组件。也就是说,你可以在多个activity中引用同一个fragment,因为fragment定义了它自己的布局,并且使用它本身生命周期回调的行为。
Fragment比Activity多了几个额外的生命周期回调方法:
管理fragment生命周期与管理activity生命周期很相像,像activity一样,fragment也有三种状态:
1、Resumed:
fragment在运行中的activity中可见。
2、Paused:
另一个activity处于前台且得到焦点,但是这个fragment所在的activtiy仍然可见(前台activity部分透明,或者没有覆盖全屏)。
3、Stopped:
fragment不可见。要么宿主activity已经停止,要么fragment已经从activity上移除,但已被添加到后台栈中。一个停止的fragment仍然活着(所有的状态和成员信息仍然由系统保留着)。但是,它对于用户来讲已经不再可见,并且如果activity被杀掉,它也将被杀掉。
如果activity的进程被杀掉了,在activity被重新创建时,你恢复fragment状态。可以执行fragment的onSaveIntanceState()来保存状态(注意:fragment是在onCreate(),onCreateView()或者onActivityCreate()中进行恢复)。
在生命周期方面,activity和fragment之间一个很重要的不同就是在各自的后台栈中是如何存储的。当activity停止时,默认情况下activity被安置在由系统管理的activity后台栈中;fragment仅当在一个事务被移除时,通过显式调用addToBackStack()请求保存的实例,该fragment才被置于由宿主activity管理的后台栈。
类似与Android系统为Activity维护一个任务栈,我们也可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化。
如果你将Fragment任务添加到回退栈,当用户点击后退按钮时,将看到上一次的保存的Fragment。一旦Fragment完全从后退栈中d出,用户再次点击后退键,则退出当前Activity。
通过Arguments创建Fragment,不建议通过为Fragment添加带参数的构造函数
1、FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例。
2、FragmentStatePagerAdapter:会销毁不再需要的fragment,当当前事务提交以后,会彻底的将fragment从当前Activity的FragmentManager中移除。
3、懒加载,核心方法是 setUserVisibleHint()
原因1:横竖屏切换,造成Fragment重新实例化。
原因2:按下Home键,Activity处于后台,由于内存不足被销毁,重新唤醒时Fragment重新实例化。
注:出现的原因是在 API24 之前的 v4包 的源码问题,
解决方案:通过检查onCreate的参数Bundle savedInstanceState就可以判断,当前是否发生Activity的重新创建:
默认的savedInstanceState会存储一些数据,只有在savedInstanceState==null时,才进行创建Fragment实例:
首先调用Activity的onCreate和onStart,然后Fragment会连续的从onAttach到onStart,然后调用Activity的onResume,最后是Fragment的onResume。
** 值得注意的是Fragment的onSart方法可能是在Fragment的onSart方法之前被调用,而且Fragment从onAttach到onStart是一个连续的执行。
add一个Fragment的时候不管之前是否有其他的Fragment,其他的Fragment是以什么方式加进去的,都会从onAttach方法开始走到onResume
onAttach --> onCreate --> onCreateView --> onActivityCreated --> onStart -->onResume
如果之前没有Fragment 直接Replace 相当于Add
onAttach --> onCreate --> onCreateView --> onActivityCreated --> onStart -->onResume
如果之前有一个Fragment A ,然后现在要 B replace A
B: onAttach --> onCreate
A: onPause --> onStop --> onDestroyView -->onDestory -->onDetach (onDestory、onDetach取决于A是否有添加到回退栈)
B: onCreateView --> onActivityCreated --> onStart -->onResume
当remove一个fragment的时候,它的生命周期跟是否添加到回退栈( addToBackStack )有关系。如果Fragment被添加到回退栈中的话,销毁时只会销毁View,生命周期走到onDestroyView,不会把整个Fragment销毁,跟Activity断开关联
onPause --> onStop --> onDestroyView --> onDestory --> onDetach (onDestory、onDetach取决于A是否有添加到回退栈)
通过 hide() 、 show() 来隐藏、显示Fragment,此时 Fragment 只改变了可见性,并不涉及生命周期的改变
commit、commitNow、commitAllowingStateLoss、commitNowAllowingStateLoss
commit 是异步 *** 作,会将任务提交给主线程,
commitNow 会立即执行事务
commitAllowingStateLoss 和 commit的区别就是:commit如果在onSaveInstanceState之后提交会抛出IllegalStateException(无效状态异常)
状态的丢掉,指的是可能丢掉FragmentManager状态, 即onSaveInstanceState之后任何被添加或被移除的Fragments.
遇到的问题:通过FragmentTransaction的replace方法会导致,每次都会重新调用fragment的onCreateView()方法,浪费时间。
解决方法:
通过FragmentTransaction的hide和show方法来实现fragment的显示和隐藏,这样就不会重复调用onCreateView函数了。
FragmentTransactioin 可以用来添加,删除fragment,也可以控制fragment的显示和隐藏。
这是如果调用addToBackStack(null),此时的状态就会被保存在回退栈,按返回键的时候就会显示出栈顶的
getSupportFragmentManager().popBackStack() 这个方法可以让栈顶的fragment出栈。
只有在程序运行时被动态添加的fragment才会被添加到后退栈。
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, newFragment,"testa")
.addToBackStack(null)
.commit()
程序跑起来之后,通过这个方法后退栈数才会加一,如果在代码中一口气添加多个,再运行程序,getSupportFragmentManager().getBackStackEntryCount()得到的后退栈数值为零。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)