1.Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。

2.Fragment 生命周期:

伯乐在线 > 首页 > 所有文章 > Android > Android Fragment生命周期——多屏幕支持

Android Fragment生命周期——多屏幕支持

2014/04/03 | 分类: Android, 开发 | 0 条评论 | 标签: Android

分享到: 8
本文由 伯乐在线 - chris 翻译。未经许可,禁止转载!
英文出处:javacodegeeks。欢迎加入翻译小组

在使用Fragment之前,Fragment的生命周期是一个需要关心的问题。目前,要想在Android上开发出一款APP必须得考虑到“碎片化”的问题,或者说必须考虑多屏幕适配,这是每一个开发者都必须面对的问题。

现在市场上手机的屏幕分辨率、尺寸五花八门,更糟糕的是,除了手机外还有平板!我们都清楚,就单单屏幕尺寸来说手机和平板差异很大。所以,当我们开
发应用程序的时候,要谨记我们的APP应该能适用于不同的设备上而且必须达到最优效果,这样才能确保获得更佳用户体验。于是问题就产生了,我们需要调整应
用在手机和平板上显示相同的效果,也就是现在所说的多屏幕适配。在之前的一篇帖子里,我已经讲了怎么用Android的一些特性做多屏幕支持,比如创建不同的布局文件等等。这个方式现在也还可以这么做,但是已经不能满足我们的要求了。

一个经典的例子是,应用中有一个列表,用户点击列表条目就可以显示详细信息。这种情况下,我们可以使应用在手机和平板上有不同的体验效果。在手机上需要两个Activity来完成这个功能,如图:

当用户点击后,出现的界面是这样的:

而在平板上,我们我们需要好好利用屏幕,把列表和详情显示在一起,如图:

从上面的例子我们清楚地看到,我们需要一个方法去“合并Activity”,让其中一个Activity调用另一个时,两个Activity都能同时或者先后显示。我们需要在不重写代码的情况下重新组织界面布局,而仅仅使用多布局来做是不行的,我们需要别的技术。

Fragment

在Android3.0上引入了一个新概念叫Fragment。它有自己的布局文件,可以作为组件排布,也可以
相互组合去实现不同的布局显示。使用Fragment可以重复利用代码,并且可以满足不同设备尺寸的需求。Fragment不能单独存在,只能存在于
Activity中,而一个Activity可以拥有多个Fragment。很重要的一点是,Fragment可以和Activity中的其它组件一起使
用,无需重写所有Activity的接口。所以使用Fragment就可以这样来完成上例中“主界面—详细界面”的APP需求。

在手机上是这样显示的:

而在平板上是这样的:

Fragment生命周期

既然我们已经知道了Fragment很好用,那么我们也需要知道它的工作原理。Fragment只能存在于(作为容器的)Activity中,每一
个Fragment都有自己的视图结构,可以像我们之前那样载入布局。Fragment的生命周期更加复杂,因为它有更多的状态,如图:

Fragment完整的生命周期。

    • 在Fragment生命周期开始,onInflate方法被调用。要注意的是,这个方法只在我们直接用标签在布局文件中定义的时候才会被调用。我们可以在这个方法中保存一些在xml布局文件中定义的配置参数和一些属性。
    • 这一步过后就轮到onAttach被调用了。这个方法在Fragment绑定到它的父Activity中的时候被调用,我们可以在这里保存它和Activity之间的引用。
    • 之后onCreate会被调用。这是最重要的步骤之一。Fragment就是在这一步中产生的,可以用这个方法来启动其它线程来检索数据,比如从远程服务器中启动。
    • onCreateView这个方法是在Fragment创建自己的视图结构的时候被调用,在这个方法中我们会载入Fragment的布局文件,就像我们在ListView控件中载入布局一样。在这个过程中,我们不能保证父Activity是否已经创建,所以有一些操作我们不能在这里完成。
    • 可以看到,在onActivityCreated后Activity才算是建立完成。到这一步,我们的Activity就创建成功并激活了。我们可以随时使用它了。
    • 下一步就是onStart了,在这里我们做的事和Activity中的onStart一样,在这个方法中Fragment虽然可以显示,但是还不能和用户进行交互,只有在onResume后Fragment才能开始和用户进行交互操作。在这个过程后,Fragment就已经启动并运行起来了。
    • 也许会暂停Activity。Activity的OnPause方法会被调用。这时候Fragment的onPause方法也会被调用。
    • 系统也可能会销毁Fragment的视图显示,发生这种情况时onDestroyView方法就被调用了。
    • 之后,如果系统需要完全销毁整个Fragment的话,onDestroy方法就会被调用了。这时候我们就需要释放掉所有可用的连接了,因为这个时候Fragment马上就要被杀掉了。虽然是在准备销毁的过程中,但是Fragment仍然绑定在父Activity中。
    • 最后一步就是把Fragment从Activity中解绑,即调用onDetach方法。

Activity直接影响它所包含的fragment的生命周期,所以对activity的某个生命周期方法的调用也会产生对fragment相同方法的调用。例如:当activity的onPause()方法被调用时,它所包含的所有的fragment们的onPause()方法都会被调用。

Fragment比activity还要多出几个生命周期回调方法,这些额外的方法是为了与activity的交互而设立,如下:

onAttach()

当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。

onCreateView()

当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。

onActivityCreated()

当activity的onCreated()方法返回后调用此方法。

onDestroyView()

当fragment的layout被销毁时被调用。

onDetach()

当fragment被从activity中删掉时被调用。

一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。

3.必须实现的三个回调函数

  onCreate()

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

  onCreateView()

  当第一次绘制Fragment的UI时系统调用这个方法,必须返回一个View,如果Fragment不提供UI也可以返回null。

  注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。

  onPause()

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

4.把Fragment加入Activity

  当Fragment被加入Activity中时,它会处在对应的View Group中。

  Fragment有两种加载方式:一种是在Activity的layout中使用标签<fragment>声明;另一种方法是在代码中把它加入到一个指定的ViewGroup中。

  另外,Fragment它可以并不是Activity布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。

加载方式1:通过Activity的布局文件将Fragment加入Activity

加载方式2:通过编程的方式将Fragment加入到一个ViewGroup中

  当Activity处于Running状态下的时候,可以在Activity的布局中动态地加入Fragment,只需要指定加入这个Fragment的父View Group即可。

  首先,需要一个FragmentTransaction实例:

 FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

(注,如果import android.support.v4.app.FragmentManager;那么使用的是:FragmentManager fragmentManager = getSupportFragmentManager();)

之后,用add()方法加上Fragment的对象:

 ExampleFragment fragment = new ExampleFragment();

 fragmentTransaction.add(R.id.fragment_container, fragment);

 fragmentTransaction.commit();

 其中第一个参数是这个fragment的容器,即父控件组。

 最后需要调用commit()方法使得FragmentTransaction实例的改变生效。

最新文章

  1. sharepoint2013的审核日志的时间区域设置
  2. Gesture Recognizers与触摸事件分发[转]
  3. Java基础之泛型——使用泛型链表类型(TryGenericLinkedList)
  4. LaTeX新人教程,30分钟从完全陌生到基本入门
  5. Sqlserver通过链接服务器访问Oracle的解决办法
  6. jQuery中的ajax使用详解
  7. pythonl练习
  8. 转:一篇讲线上优化查 CPU的脚本
  9. python socket连接服务器获取回显
  10. JS判断PC还是移动端打开网页
  11. 用nginx缓存静态文件
  12. js之Ajax下载文件
  13. servlet设置cookie
  14. Python-复习-文件操作-21
  15. 深入理解读写锁ReentrantReadWriteLock
  16. HTML5使用详解
  17. Spring注解@Value
  18. XAMPP环境的搭建
  19. Mac 远程连接 Windows 系统无法全屏
  20. php学习笔记-if else

热门文章

  1. Mysql notes
  2. Java知识积累2-StringReverse实现文字(单词)倒叙输出
  3. log4jWARN Please initialize the log4j system properly解决办法
  4. mybatis入门_一对多,多对多映射以及整合spring框架
  5. Struts2配置Result(Struts2_result)
  6. 编译2.4.X apache 常见错误
  7. linux建立一个快捷方式,连接到另一个目录
  8. JDBC与Hibernate中SQL语句参数设置的顺序问题
  9. Oracle转MySQL
  10. 加速编码的 JavaScript 库和工具