Fragment 相关知识点

作者: zcwfeng | 来源:发表于2020-07-17 16:45 被阅读0次

    生命周期

    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创建的时候,setUserVisibleHint()传入false
    • 当Fragment可见时候,setUserVisibleHit()传入true
    • 当Fragment 可见----> 不可见的时候,setUserVisibleHint 被调用,切传入false

    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 提供了共享数据的机制

    相关文章

      网友评论

        本文标题:Fragment 相关知识点

        本文链接:https://www.haomeiwen.com/subject/zqzghktx.html