移动 前端 Python Android Java

Fragment 相关知识点

2020-07-17  本文已影响0人  zcwfeng

生命周期

activity_fragment_lifecycle

Fragment 通信

  1. 在Fragment 中调用Activity中的方法,getActivity()方法获取所附属的Activity中的方法
  2. 在Activity中调用Fragment中的方法 采用接口回调的形式
  3. 在Fragment中调用Fragmetn的方法findFragmentById()

replace add Remove

add 是吧一个Fragment添加到一个容器当中,一般在add的时候为了避免重复创建Fragment节省资源,会配合hide 和 replace使用

replace 在添加fragment到容器之前先移除掉相同id的所有Fragment在进行添加

remove 就是移除fragment 没必要多说

对于Fragment操作都会使用Fm得到一个FragmentTransaction事务对象。在一个Activity+多个Fragment的回退处理,使用hide,show这样同级的用着可以。
但是对于导航栏类似功能,多个功能回退就不好用了,此时可以使用addToBackStck,popBackStack 实现。

多个Fragment :

FragmentStatePagerAdapter 和 FragmentPagerAdapter

选择

当Viewpager中fragment数量多的时候用FragmentStatePagerAdapter,反之则用FragmentPagerAdapter

相同点

两者都会保持当前item(即fragment)和前后的item的状态。
显示当前item的同时,Adapter会提前初始化后一个item,并把当前item的前一个 item保存在内存中。

不同点:

在于fragment 存储、恢复、销毁 的方式不同

对滑动过去的页面是否销毁:
例如:依次从左向右有fragment1,fragment2,fragment3三个页面

FragmentPagerAdapter在滑动到fragment3时,fragment1会依次调用onPause()、onStop()、onDestroyView(),再向左滑动到fragment2时,fragment1会调用onCreateView()、onActivityCreated()、onStart()、onResume()。
结论:FragmentPagerAdapter会保留页面的状态,并不会完全销毁掉。

FragmentStatePagerAdapter在滑动到fragment3时,fragment1会依次调用onPause()、onStop()、onDestroyView()、onDestroy()、onDetach()方法,再向左滑动到fragment2时,fragment1会调用onAttach()、onCreate()、onCreateView()、onActivityCreated()、onStart()、onResume()。
结论:FragmentStatePagerAdapter会完全销毁滑动过去的item,当需要初始化的时候,会重新初始化页面。

commit() 与 commitAllowingStateLoss()

Activity 被系统回收(界面已经不存在了),为了能在下次打开的时候恢复原来的样子,我们保存页面所有状态,这个时候再去修改界面是不允许的。为了避免这种异常可以用:

transaction.commit AllowingStateLoss()

与commit()不同的是允许丢失页面的状态和信息

Adapter 与Fragment

FragmentPagerAdapter 一般用于少量界面的ViewPager,划过Fragment会一直保存到内存不销毁。
FragmentStatePageAdapter使用与界面较多的ViewPager,他会保存当前界面,上一个界面和下一个界面,最多保存三个,其他的在destroyItem()方法销毁调用,节省内存。

ViewPager 与 Fragmetn结合使用懒加载问题

Fragment初始化的时候会和网络请求一起执行,这样非常耗性能,最理想方式,只有用胡点开和滑动当前Fragment的时候在进行网络请求操作,因此产生懒加载的说法

ViewPager配合Fragment默认加载前两个,会导致网络丢包和阻塞

在Fragment有一个setUserVisibleHint方法这个方法优于onCreate方法,通过isVisibleToUser 告诉我们是否可见,我们可以在可见的时候加载网络

从log上看setUserVisibleHint 调用早于onCreateView,如果在serUserVisibleHit 实现懒加载注意在view初始化结束,避免空指针。

setUserVisibleHint 什么时候调用

Fragment 通信原则:

很重要一个原则
您常常希望 Fragment 之间能够进行通信,以实现某种目的,例如根据用户事件改变内容。所有 Fragment 间的通信通过共享的 ViewModel 或关联的 Activity 来完成。两个 Fragment 不得直接通信。

FragmentManager

Fragment 解耦

通信:接口,网络,eventbus,rxbus,广播,handler

handler缺点:
    缺点:
    耦合,
    无法获取activity返回结果,handler单向通信
    内存泄露
    
广播:
    缺点:
    1.性能差,延迟(充电,重启,wifi,蓝牙,电话,短信等)单一发射源,多个接收方
    2.通信体系重,一个发生,多个接受,广播的数量是有限的
    3.传播的数据有限
    4.代码冗余

EventBus:
    缺点:
    1.通过反射,性能打折,效率低
    2.代码维护困难
    3.数据无法返回,单向传递

接口:
        简单,效率高,方便,解耦合
    缺点:
        代码冗余,每个fragment都必须定义自己的独一无二的接口
        
解决: 万能接口

    1. 定义Function抽象类,实现四种抽象类,有参数有返回值,无参数无返回值,只有参数,只有返回值
    2. 定义FunctionManager 作为管理Function接口和容器,提供单例模式对外使用
    3. 定义BaseFragment 引用FragmentManager set方法

jetpack 便捷的方式

给我们提供了只要在同一个Activity管理下,ViewModel------ViewModelProviders 提供了共享数据的机制

上一篇下一篇

猜你喜欢

热点阅读