天天看点

Android系列之Fragment(二)----Fragment的生命周期和返回栈

【正文】

一、fragment的生命周期初探:

因为fragment必须嵌入在acitivity中使用,所以fragment的生命周期和它所在的activity是密切相关的。

如果activity是暂停状态,其中所有的fragment都是暂停状态;如果activity是stopped状态,这个activity中所有的fragment都不能被启动;如果activity被销毁,那么它其中的所有fragment都会被销毁。

但是,当activity在活动状态,可以独立控制fragment的状态,比如加上或者移除fragment。

当这样进行fragment transaction(转换)的时候,可以把fragment放入activity的back stack中,这样用户就可以进行返回操作。

使用fragment时,需要继承fragment或者fragment的子类(dialogfragment, listfragment, preferencefragment, webviewfragment),所以fragment的代码看起来和activity的类似。

每当创建一个fragment时,首先添加以下三个回调方法:

oncreate():系统在创建fragment的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。

oncreateview():当第一次绘制fragment的ui时系统调用这个方法,该方法将返回一个view,如果fragment不提供ui也可以返回null。注意,如果继承自listfragment,oncreateview()默认的实现会返回一个listview,所以不用自己实现。

onpause():当用户离开fragment时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。

将fragment加载到activity当中有两种方式:

方式一:添加fragment到activity的布局文件当中

方式二:在activity的代码中动态添加fragment(荐)

第一种方式虽然简单但灵活性不够。添加fragment到activity的布局文件当中,就等同于将fragment及其视图与activity的视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。

第二种方式比较复杂,但也是唯一一种可以在运行时控制fragment的方式(加载、移除、替换)。

二、fragment的生命周期详解:

先来看一下官方文档的图片吧:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

我们再把activity的生命周期和fragment的生命周期对比一下,就清楚很多了:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

我们还是在实例中来看一下fragment的生命周期吧。

【实例】在mainactivity中加载一个fragment:(完整版代码如下)

我们所创建的fragment的布局文件fragment01.xml的代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

myfragment.java代码如下:(注意生命周期中每个方法的作用)

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

activity_main.xml的代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

mainactivity.java的代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

可以看到,上面的代码在每个生命周期的方法里都打印了日志,然后我们来运行一下程序,可以看到打印日志如下:

初次加载:(分成两部分来看)

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

点击一下home键(或接入电话),打印日志如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

重新进入进入程序(或电话结束),打印日志如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

点击back键退出程序,打印日志如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

通过上面的日志,我们能够看出,fragment和activity的生命周期太相似了。只是有几个activity中没有的新方法,需要重点介绍一下:

onattach方法:fragment和activity建立关联的时候调用(获得activity的传递的值)

oncreateview方法:为fragment创建视图(加载布局)时调用(给当前的fragment绘制ui布局,可以使用线程更新ui)

onactivitycreated方法:当activity中的oncreate方法执行完后调用(表示activity执行oncreate方法完成了的时候会调用此方法)

ondestroyview方法:fragment中的布局被移除时调用(表示fragment销毁相关联的ui布局)

ondetach方法:fragment和activity解除关联的时候调用(脱离activity)

三、fragment返回栈的管理:

将fragment添加到返回栈中:

假设现在我们有两个fragment:fragment01和fragment02,我们现在从fragment01的界面跳到fragment02,然后按back键,发现程序是直接退出了,而不是返回到fragment01。如果现在想实现以下功能:从fragment01的界面跳到fragment02,然后按back键,会返回到fragment01。这个功能该怎么实现呢?这其实就利用到了返回栈的知识。

其实很简单,fragmenttransaction中提供了一个addtobackstack()方法,可以将一个事务添加到返回栈中。

我们先回顾一下之前动态加载fragment的代码,然后在此基础之上,增加一行代码就可以将fragment添加到返回栈中:(即第07行代码)

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

第07行代码:我们在事务提交之前调用了fragmenttransaction的addtobackstack()方法,它可以接受一个名字用于描述返回栈的状态,,一般传入null即可。

【实例】现在通过代码来实现以下界面(下面的图片为程序运行时加载的首页),并且把每一个fragment都加入到返回栈当中去,然后观察其生命周期的变化。完整代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

首先新建工程文件m01_fragment04,然后开始我们的代码之旅:

我们先把右侧的四个fragment建起来吧:

fragment01.java主要部分的代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

为避免啰嗦,这里就不把fragment01生命周期中的其他函数罗列出来了,我们只要知道在实际代码中这些函数都是加了的。

fragment01的布局文件f1.xml的代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

然后依次新建出fragment02、fragment03、fragment04的java代码和布局文件。

mainactivity的布局文件activity_main.xml代码如下:

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

其中,第一个linearlayout表示左侧的按钮,第二个linearlayout留给右边的fragment。

Android系列之Fragment(二)----Fragment的生命周期和返回栈
Android系列之Fragment(二)----Fragment的生命周期和返回栈

上当代码中,通过点击不同的按钮,就能跳到对应的fragment,而这四个fragment都已经加入到了返回栈当中。运行程序之后,也是这样的。

注意第46行和第72行,transaction = manager.begintransaction()意味着开始,transaction.commit()意味着结束。

我们就其中的fragment01和fragment02来讨论一下他们的生命周期的变化:

运行程序后,界面如下,没有任何fragment被加载:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

点击左侧第一个按钮,加载fragment01:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

点击左侧第二个按钮,加载fragment02(此时fragment01被替换,并被压到了栈当中):

Android系列之Fragment(二)----Fragment的生命周期和返回栈

注:如果fragment01在替换的时候没有被压到栈中,那就会被销毁,在执行完ondestroyview()方法后,会继续执行ondestroy()和ondetach()方法。

按back键,fragment01重新返回到屏幕:(fragment02被销毁)

Android系列之Fragment(二)----Fragment的生命周期和返回栈

再按back键,fragment01被销毁:

Android系列之Fragment(二)----Fragment的生命周期和返回栈

 注:fragment的返回栈由activity管理;而activity的返回栈由系统管理。

继续阅读