Android之 Fragment

一、定义

Fragment指碎片。是Activity界面中的一部分,可理解为模块化的Activity。
(1)Fragment不能独立存在,必须嵌入到Activity中
(2)Fragment具有自己的生命周期,接收它自己的事件,并可以在Activity运行时被添加或删除
(3)Fragment的生命周期直接受所在的Activity的影响。如:当Activity暂停时,它拥有的所有Fragment们都暂停

二、作用

为了解决不同屏幕分辩率的动态和灵活UI设计

  • 模块化+复用
    一个Fragment相当于一个Activity模块,可将业务逻辑分离,并且为多个Activity使用
  • UI灵活
    能够比较容易适配手机和平板,根据屏幕的宽度决定Fragment的放置
  • 占内存小
    Fragment轻量不消耗手机资源,启动顺滑流畅。而Activity的启动设置Android系统对ActivityManager的调度,会关联许多资源和进行诸多复杂运算

三、生命周期

生命周期方法解析

1、 onAttach:Fragment和Activity建立关联的时候调用,可以获得对应的Context或Activity,这里拿到的Activity是mHost.getActivity()
2、 onCreate:Fragment对象初始创建,用于执行初始化操作。
由于Fragment的onCreate调用时,关联的Activity可能没有创建好,所以不要有依赖外部Activity布局的操作。依赖Activity的操作可以放在onActivityCreate中。
3、 onCreateView:为Fragment创建视图(加载布局)时调用(给当前的fragment绘制UI布局,可以使用线程更新UI)
4、 onActivityCreated:当与Fragment关联的Activity中的onCreate方法执行完后调用(表示activity执行onCreate方法完成了的时候会调用此方法)
这个方法里做些和布局、状态恢复有关的操作,如
onViewStateRestored(Bundle)用于一个Fragment在从就状态回复,获取saveInstanceState恢复状态。
以上4步同步于Activity的onCreate
5、 onStart:Fragment可见时调用,将Fragment对象显示给用户。同步于Activity的onStart
6、 onResume:Fragment对象可见并可与用户交互时调用。同步于Activity的onResume
7、 onPause:Fragment对象与用户不再交互。同步于Activity的onPause
8、 onStop:Fragment对象不再显示给用户。同步于Activity的onStop
9、 onDestroyView:Fragment中的布局被移除时调用(表示fragment销毁相关联的UI布局)
10、onDestroy:Fragment状态清理完成
11、 onDetach:Fragment和Activity解除关联的时候调用(脱离activity)

生命周期场景

  • fragment被创建
    onAttach()–>onCreate()–>onCreateView()–>onActivityCreated()
  • fragment显示
    onStart()–>onResume()
  • fragment进入后台模式
    onPause()–>onStop()–>onDestroyView()
  • fragment被销毁(持有它的activity被销毁)
    onPause()–>onStop()–>onDestroyView()–>onDestroy()–>onDetach()
  • fragment重新恢复
    onCreateView()–>onActivityCreated()–>onStart()–>onResume()

Fragment切换生命周期变化

情况1:通过add、hide、show方式切换Fragment
1、初始化:
Fragment1载入:onCreate()->onCreateView()->onStart()->onResume()
2、Fragment1切换到Fragment2:
Fragment1隐藏:onHiddenChanged()
Fragment2载入:onCreate()->onCreateView()->onStart()->onResume()
3、Fragment2切换到Fragment1:
Fragment1:onHiddenChanged()
Fragment2:onHiddenChanged()

通过add、hide、show方式切换Fragment时所有的view都会保存在内存,不会销毁与重建

情况2:通过replace方式切换Fragment
1、初始化
Fragment1载入:onCreate()->onCreateView()->onStart()->onResume()
2、Fragment1切换到Fragment2:
Fragment1销毁:onPause()->onStop()->onDestroyView()->onDestroy()
Fragment2载入:onCreate()->onCreateView()->onStart()->onResume()
3、Fragment2切换到Fragment1:
Fragment2销毁:onPause()->onStop()->onDestroyView()->onDestroy()
Fragment1载入:onCreate()->onCreateView()->onStart()->onResume()

通过 replace 方法进行替换的时,Fragment 都是进行了销毁,重建的过程,相当于走了一整套的生命周期

情况3:通过ViewPager方式切换Fragment
1、初始化
Fragment1载入:onCreate()->onCreateView()->onStart()->onResume()
Fragment2载入:onCreate()->onCreateView()->onStart()->onResume()
2、Fragment1切换到Fragment2:
Fragment1不可见:setUserVisVleHint(false)
Fragment2可见:setUserVisVleHint(true)
3、Fragment2切换到Fragment1:
Fragment1可见:setUserVisVleHint(true)
Fragment2不可见:setUserVisVleHint(false)

1、使用ViewPager与Fragment切换时,Fragment会进行预加载操作,即所有的Fragment都会提前初始化。
2、 setUserVisVleHint()方法在 Fragment 1 第一次加载的时候不走,只有在切换的时候 走该方法。
3、主动调用 setUserVisibleHint()方法来控制第一次不会调用setUserVisibleHint方法的问题。
setUserVisibleHint()方法优先onCreateView方法,当onCreateView方法调用后还会再次调用setUserVisibleHint方法。此时要对是否调用了onCreateView()方法进行标记判断。

FragmentTransaction事务

获取事务

@Override
public FragmentTransaction beginTransaction() {
    return new BackStackRecord(this);
}

事务提交方式
(1)commit()
commit() 在主线程中异步执行,其实也是 Handler 抛出任务,等待主线程调度执行
commit() 需要在宿主 Activity 保存状态之前调用,否则会报错。
这是因为如果 Activity 出现异常需要恢复状态,在保存状态之后的 commit() 将会丢失,这和调用的初衷不符,所以会报错.
(2)commitAllowingStateLoss()
commitAllowingStateLoss() 也是异步执行,但它的不同之处在于,允许在 Activity 保存状态之后调用,也就是说它遇到状态丢失不会报错。
因此我们一般在界面状态出错是可以接受的情况下使用它。
这种方式是不安全的,因为事务提交时Activity可能还没有恢复,会丢失提交的事务
(3)commitNow()
commitNow() 是同步执行的,立即提交任务。
和 commit() 一样,commitNow() 也必须在 Activity 保存状态前调用,否则会抛异常
(4)commitNowAllowingStateLoss()
同步执行

Activity与Fragment以及Fragment之间数据传输

(1)Activity传递数据到Fragment——Bundle
1、若Fragment存在,则可通过FindFragmentById直接获得Fragment并调用Fragment的共有函数,否则在创建Fragment时将数据放入bundle,并通过setArgument传递bundle对象
(2)Fragment传递数据到Activity——接口回调

Fragment之间传递数据方式
(1)通过FragmentManager标签获得Fragment对象,调用另一个Fragment中的方法传递数据
(2)采取接口回调方式进行数据传递
(3)EventBus

show、hide、replace区别

区别
show(),hide()最终是让Fragment的View setVisibility(true还是false),不会调用生命周期;replace()的话会销毁视图,即调用onDestoryView、onCreateView等一系列生命周期;
add()和 replace()不要在同一个阶级的FragmentManager里混搭使用

场景
如果你有一个很高的概率会再次使用当前的Fragment,建议使用show(),hide(),可以提高性能。
在我使用Fragment过程中,大部分情况下都是用show(),hide(),而不是replace()。
注意:如果你的app有大量图片,这时更好的方式可能是replace,配合你的图片框架在Fragment视图销毁时,回收其图片所占的内存。

Fragment、FragmentManager、FragmentTransaction区别

  • Fragment
    其实是对 View 的封装,它持有 view, containerView, fragmentManager, childFragmentManager 等信息
  • FragmentManager
    是一个抽象类,它定义了对一个 Activity/Fragment 中 添加进来的 Fragment 列表、Fragment 回退栈的操作、管理方法,还定义了获取事务对象的方法,具体实现在 FragmentImpl 中
  • FragmentTransation
    定义了对 Fragment 添加、替换、隐藏等操作,还有四种提交方法,具体实现是在 BackStackRecord 中

getFragmnetManager , getSupportFragmentManager , getChildFragmentManager 三者的区别

  • getFragmentManager()所得到的是所在fragment 的父容器的管理器。
  • getChildFragmentManager()所得到的是在fragment 里面子容器的管理器。
  • getSupportFragmentManager()主要用于支持 3.0以下android系统API版本,3.0以上系统可以直接调用getFragmentManager()
    注:getFragmentManager得到的是activity对所包含fragment的Manager,而如果是fragment嵌套fragment,那么就需要利用getChildFragmentManager()

FragmentPagerAdapter , FragmentStatePagerAdapter 的区别

  • FragmentPagerAdapter
    使用FragmentPagerAdapter 时,Fragment对象会一直存留在内存中,所以当有大量的显示页时,就不适合用FragmentPagerAdapter了,FragmentPagerAdapter 适用于只有少数的page情况,像选项卡。
    原因:步长外的页面会调用destroyItem,但只有onDestroyView调用了,没有调用onDestory,也没有调用onDetach,所以fragment只是把上面的view销毁了,fragment并没有销毁,下次再创建的时候,只会调用onCreateView和onActivityCreated
  • FragmentStatePagerAdapter
    这个时候你可以考虑使用FragmentStatePagerAdapter ,当使用FragmentStatePagerAdapter 时,如果Fragment不显示,那么Fragment对象会被销毁,(滑过后会保存当前界面,以及下一个界面和上一个界面(如果有),最多保存3个,其他会被销毁掉)
    原因:会真正销毁(同时销毁view和fragment,调用onDestroyView以及其后面的所有销毁方法),重建时会从最初的onAttach开始一直到onActivityCreated。但在回调onDestroy()方法之前会回调onSaveInstanceState(Bundle outState)方法来保存Fragment的状态,下次Fragment显示时通过onCreate(Bundle savedInstanceState)把存储的状态值取出来,FragmentStatePagerAdapter 比较适合页面比较多的情况,像一个页面的ListView 。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值