Fragment 使用和坑

一、Framgnet 为什么被称为 第五大组件

fragment 相比于activity更加节约内存,fragment 可以灵活的在activity中加载、切换,同时也有自己的生命周期

Fragment 优点

  • Fragment 可以将 Activity 分离成多个可重用的组件,每个都有它自己的生命周期和 UI。
  • Fragment可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑,在不同的安卓设备上统一你的UI。
  • Fragment是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。
  • Fragment解决Activity之间的切换不流畅,轻量切换。 Fragment替换TabActivity做导航性能更好。

二、Fragment 加载到 Activity 的两种方式

1、静态加载:直接写入到 layout 中
2、动态加载:使用FragmentManager进行管理(通常使用 supportFragmentManager),开启 transaction ,添加以后,commit

三、FragmentPagerAdapter 与 FragmentStatePagerAdapter

前者适用于页面较少的情况,后者适用于页面较多的情况。FragmentStatePagerAdapter 在每次view pager 切换页面的时候,是回收了内存的。前者只是调用了 detach 方法和activity分开,没有释放内存。

使用FragmentPagerAdapter+ViewPager时,切换回上一个Fragment页面时(已经初始化完毕),不会回调任何生命周期方法以及onHiddenChanged(),只有setUserVisibleHint(boolean isVisibleToUser)会被回调,所以如果你想进行一些懒加载,需要在这里处理

在给ViewPager绑定FragmentPagerAdapter时,new FragmentPagerAdapter(fragmentManager)的FragmentManager,一定要保证正确,如果ViewPager是Activity内的控件,则传递getSupportFragmentManager(),如果是Fragment的控件中,则应该传递getChildFragmentManager()。只要记住ViewPager内的Fragments是当前组件的子Fragment这个原则即可。

参考

三、Fragment 的生命周期

onAttach:
onCreate: 创建 fragment
onCreateView: 加载布局
(onViewCreated): 表明fragment的UI已经绘制好了
onActivityCreated: 只有activity的onCreate调用以后才会调用这个方法
onStart: 优先调用activity的 onstart 方法
onResume: 优先调用activity的 onresume 方法 。到此,fragment已经初始化完成

onPause:
onStop:
onDestroyView:
onDestory:
onDetach()

四、Fragment 之间的通信

1、在fragment中调用activity中的方法 getActivity
2、在activity中调用Fragment中的方法,接口回调(在fragment中创建接口,使用activity调用接口)
3、在Fragment中调用Fragment中的方法,首先获取到activity,然后通过这个activity调用另外一个 fragment的方法
4、如果要从 A 中 启动 B,并且需要在 B 关闭后返回数据给 A。在A中启动的时候设置 B.targetFragment(A),B中调用 getTargetFragment.onActivityResult().

五、FragmentTransaction

show(),hide()最终是让Fragment的View setVisibility(true还是false),不会调用生命周期

replace()的话会销毁视图,即调用onDestoryView、onCreateView等一系列生命周期

当使用add()+show(),hide()跳转新的Fragment时,旧的Fragment回调onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged(),这点要切记。

对于宿主Activity,getSupportFragmentManager()获取的FragmentActivity的FragmentManager对象;

对于Fragment,getFragmentManager()是获取的是父Fragment(如果没有,则是FragmentActivity)的FragmentManager对象,而getChildFragmentManager()是获取自己的FragmentManager对象。

六、getActivity ==null

正常情况下,我们在 Framgnet 中使用 Context,是直接 getActivity()。
在系统异常重启的时候,也就是 Activity 因为内存紧张或者是旋转屏幕被系统杀掉,如果我们通过 getActivity() 去获取 Context 可能就获取不到,因为 Framgent 已经从容器 Activity 中 detach 了,这种时候,我们可以在 Framgnet 基类中的 onAttch(Context context) 方法中设置一个全局变量 mActivity,这样,即使是 Fragment 从 Activity 中 detach 了,仍然持有 Activity 引用。

虽然这样的方法可能导致内存泄露,但是不失为一种解决办法。

六、优秀的 Framgent 开源库

https://github.com/YoKeyword/Fragmentation

参考:
Fragment进阶-commit使用细节及源码分析
Fragment提交transaction导致state loss异常
Fragment 全解析系列

猜你喜欢

转载自blog.csdn.net/xiao6gui/article/details/80799870