(原创) fragment生命周期研究(fragment学习系列笔记一)

一、生命周期

为了直观,先上图:

官方文档上的解释是:
onAttach(Activity)  called once the fragment is associated with its activity.
当该fragment关联上activity的时候调用
onCreate(Bundle)  called to do initial creation of the fragment.
当初始化创建fragment的时候调用
onCreateView(LayoutInflater, ViewGroup, Bundle)  creates and returns the view hierarchy associated with the fragment.
创建并返回相关的视图层级fragment
onActivityCreated(Bundle)  tells the fragment that its activity has completed its own  Activity.onCreate() .
告诉该fragment他所关联的activity已经完成他本身的初始化(即Activity.onCreate()已经执行)
onViewStateRestored(Bundle)  tells the fragment that all of the saved state of its view hierarchy has been restored.
告诉fragment他的视图层级的保存状态已经被存储
onStart()  makes the fragment visible to the user (based on its containing activity being started).
fragment对用户可见(根据包含他的activity是否已经start)
onResume()  makes the fragment interacting with the user (based on its containing activity being resumed).
fragment可以跟用户交互(根据包含他的activity是否已经resume)

As a fragment is no longer being used, it goes through a reverse series of callbacks:

onPause() fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.

fragment不再跟用户交互,因为他的activity已经pause或者其他的一个fragment操作在activity中改变了他

onStop() fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.

fragment不再对用户可见,因为他的activity已经stop或者其他的一个fragment操作在activity中改变了他

onDestroyView() allows the fragment to clean up resources associated with its View.

允许fragment清理资源相关联的视图

onDestroy() called to do final cleanup of the fragment's state.

最终清理fragment的状态的时候被调用

onDetach() called immediately prior to the fragment no longer being associated with its activity.

fragment不再关联activity之前调用

通过实例操作得出以下结论:
在布局文件中先用FrameLayout(或者是LinearLayout、RelativeLayout)占地,然后在代码中替换
如果是用replace
manager = getFragmentManager();
transaction=manager.beginTransaction();
transaction.replace(R.id.fragment, fragment1);
transaction.commit();
生命周期的执行顺序是,先把上一个fragment的结束的生命周期执行一遍,然后新替换的fragment的开始的生命周期执行一遍
Log如下:
04-12 17:42:24.890: D/Fragment2(13321): onPause
04-12 17:42:24.890: D/Fragment2(13321): onStop
04-12 17:42:24.890: D/Fragment2(13321): onDestroyView
04-12 17:42:24.890: D/Fragment2(13321): onDestroy
04-12 17:42:24.890: D/Fragment2(13321): onDetach
04-12 17:42:24.890: D/Fragment1(13321): onAttach
04-12 17:42:24.890: D/Fragment1(13321): onCreate
04-12 17:42:24.890: D/Fragment1(13321): onCreateView
04-12 17:42:24.890: D/Fragment1(13321): onActivityCreated
04-12 17:42:24.890: D/Fragment1(13321): onStart
04-12 17:42:24.890: D/Fragment1(13321): onResume
估计是因为要把之前的fragment先remove掉,再对新替换的fragment做add操作

这样的话我们在代码中就不太好控制,比如我们想创建了一次fragment之后再打开它的时候不需要创建,还有另外一种写法:
		transaction = manager.beginTransaction();
		if (fragment1 != null && !fragment1.isDetached())//&& !fragment1.isDetached()也许可以不要

			transaction.detach(fragment1);
		if (fragment2 != null && !fragment2.isDetached())//&& !fragment2.isDetached()也许可以不要

			transaction.detach(fragment2);

		if (fragment2 == null) {
			fragment2 = new Fragment2();
		}
		if (manager.findFragmentByTag(Fragment2.TAG) == null) {
			transaction.add(R.id.fragment, fragment2,Fragment2.TAG);
		} else {
			transaction.attach(fragment2);
		}
		transaction.commit();

第一次显示fragment1的时候执行全部的生命周期的方法,Log如下:
04-12 17:57:03.930: D/Fragment1(13913): onAttach
04-12 17:57:03.930: D/Fragment1(13913): onCreate
04-12 17:57:03.930: D/Fragment1(13913): onCreateView
04-12 17:57:03.990: D/Fragment1(13913): onActivityCreated
04-12 17:57:04.000: D/Fragment1(13913): onStart
04-12 17:57:04.000: D/Fragment1(13913): onResume

当fragment2显示之后再跳回到fragment1的时候执行的方法就少了一些,Log如下:
04-12 17:58:04.300: D/Fragment2(13913): onPause
04-12 17:58:04.300: D/Fragment2(13913): onStop
04-12 17:58:04.300: D/Fragment2(13913): onDestroyView
04-12 17:58:04.310: D/Fragment1(13913): onCreateView
04-12 17:58:04.310: D/Fragment1(13913): onActivityCreated
04-12 17:58:04.310: D/Fragment1(13913): onStart
04-12 17:58:04.310: D/Fragment1(13913): onResume

综上:add或者replace执行的方法顺序为:onAttach-->onCreate-->onCreateView-->onActivityCreated-->onStart-->onResume
被替换的fragment执行的方法顺序为: onPause-->onStop-->onDestroyView-->onDestroy-->onDetach
用attach执行的顺序为:onCreateView-->onActivityCreated-->onStart-->onResume
detach(即被替换的fragment)执行的顺位为:onPause-->onStop-->onDestroyView
可能的原因是:当一个fragment被添加到视图树以后不用去移除他,当别的fragment进来的时候把他detach即脱离activity(注意:这一点必须要做,要不然新进来的fragment显示不了),进来的fragment如果不存在视图树里面就添加(添加后应该是在视图树的底层),如果存在就attach即挂载到activity,这样该fragment就在最顶层显示了。
 
另外fragment的几个is方法(如:isAdded(),isDetached(),isInLayout())也很令人蛋疼,官方文档给出的解释是:
public final boolean isAdded ()

Return true if the fragment is currently added to its activity

public final boolean isDetached ()

Return true if the fragment has been explicitly detached from the UI. That is, FragmentTransaction.detach(Fragment) has been used on it


经过测试:我add了一个fragment查看他的isAdded方法得到的却是false,detach了之后isDetached得到的也是false,这让我百撕不得骑姐。
老衲经过一袋烟的功夫思考,问题的原因可能是:这是在一个事务(transaction)中操作的,所以在提交之间是没有进行操作的,提交之后其实也是看不到的,只有在下一次事务开始之后能看到本次事务开始之前fragment的状态

PS:fragment在退回到桌面或屏幕变黑和回到程序或屏幕点亮执行的生命周期方法分别是:onPause-->onStop和onStart-->onResume



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值