1.1.1. Fragment
1.Fragment生命周期
相比Activity生命周期onCreate()对应有四个函数
- onAttach()
- onCreate()
- onCreateView()
- onActivityCreated()
相对onDestory()有三个函数
- onDestoryView()
- onDestory()
- onDetach()
2.Fragment和Activity如何交互?
fragment 不通过构造函数进行传值的原因是因为横屏切换的时候获取不到值。
2.1 Activity把数据传递给Fragment
-使用Bundle来传递数据 fragment.setArguments(bundle)
Fragment把数据传递给Activity
- 使用回调接口
- 在Fragment内getActivity();
Fragment之间传递
- 通过FragmentManager
3.FragmnetPageAdapter 对比FragmentPageStateAdapter
- FragmnetPageAdapter 在每次切换页面时,只是将 Fragment 进行分离,适合页面 较少的 Fragment 使用以保存一些内存,对系统内存不会多大影响。
- FragmentPageStateAdapter 在每次切换页面的时候,是将 Fragment 进行回收,适 合页面较多的 Fragment 使用,这样就不会消耗更多的内存
4.Fragment 如何实现类似 Activity 栈的压栈和出栈效果的?
Fragment 的事物管理器内部维持了一个双向链表结构,该结构可以记录我们每次 add 的 Fragment 和 replace 的 Fragment,然后当我们点击 back 按钮的时候会自动帮我们实现退栈操作
//实现源码 在 BackStackRecord 中
public FragmentTransaction addToBackStack(String name) {
if (!mAllowAddToBackStack) {
throw new IllegalStateException(
"This FragmentTransaction is not allowed to be added to the back
stack."); }
mAddToBackStack = true; mName = name;
return this;
} //上面的源码仅仅做了一个标记
除此之外因为我们要使用 FragmentManger 用的是 FragmentActivity,因此 FragmentActivity 的 onBackPress 方法必定重新覆写了
5.Fragment优点(为什么Android设计出Fragment)
Fragment 可以使你能够将 activity 分离成多个可重用的组件,每个都有它自己的生命周期和 UI。
Fragment 可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
- Fragment 是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。
- Fragment 提供一个新的方式让你在不同的安卓设备上统一你的 UI。
- Fragment 解决 Activity 间的切换不流畅,轻量切换。
6.api 区别
6.1 add show 和 replace
add、show方式切换 fragment 不会让 fragment 重新刷新,只会调用 onHiddenChanged(boolean isHidden)。
replace 方式会使 fragment 重新刷新,因为 add 方式是将 fragment 隐藏了而 不是销毁再创建,replace 方式每次都是重新创建。
6.2 (commit)/(commitAllowingStateLoss)
两者都可以提交 fragment 的操作,唯一的不同是第二种方法,允许丢失一些界 面的状态和信息,几乎所有的开发者都遇到过这样的错误:无法在 activity 调用 了 onSaveInstanceState 之后再执行 commit(),这种异常时可以理解的,界面 被系统回收(界面已经不存在),为了在下次打开的时候恢复原来的样子,系统为我们保存界面的所有状态,这个时候我们再去修改界面理论上肯定是不允 许的,所以为了避免这种异常,要使用第二种方法。
6.3 懒加载 setUserVisibleHint
我们经常在使用 fragment 时,常常会结合着 viewpager 使用,那么我们就会遇 到一个问题,就是初始化 fragment 的时候,会连同我们写的网络请求一起执 行,这样非常消耗性能,最理想的方式是,只有用户点开或滑动到当前 fragment 时,才进行请求网络的操作。因此,我们就产生了懒加载这样一个说 法。
Viewpager 配合 fragment 使用,默认加载前两个 fragment。很容易造成网络丢 包、阻塞等问题。 在 Fragment 中有一个 setUserVisibleHint 这个方法,而且这个方法是优于 onCreate()方法的,它会通过 isVisibleToUser 告诉我们当前 Fragment 我们是否 可见,我们可以在可见的时候再进行网络加载。
从 log 上看 setUserVisibleHint()的调用早于 onCreateView,所以如果在 setUserVisibleHint()要实现懒加载的话,就必须要确保 View 以及其他变量 都已经初始化结束,避免空指针。