原文网址:http://www.cnblogs.com/mengdd/archive/2013/01/11/2856374.html

Fragment和Activity的交互

  一个Fragment的实例总是和包含它的Activity直接相关。

  fragment可以通过getActivity() 方法来获得Activity的实例,然后就可以调用一些例如findViewById()之类的方法。

  如:

  View listView = getActivity().findViewById(R.id.list);

  但是注意调用getActivity()时,fragment必须和activity关联(attached to an activity),否则将会返回一个null。

  相似的,activity也可以获得一个fragment的引用,从而调用fragment中的方法。

  获得fragment的引用要用FragmentManager,之后可以调用findFragmentById() 或者 findFragmentByTag().

  比如:

  ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

创建事件回调

  一些情况下,可能需要fragment和activity共享事件,一个比较好的做法是在fragment里面定义一个回调接口,然后要求宿主activity实现它。

  当activity通过这个接口接收到一个回调,它可以同布局中的其他fragment分享这个信息。

  例如,一个新闻显示应用在一个activity中有两个fragment,一个fragment A显示文章题目的列表,一个fragment B显示文章。

  所以当一个文章被选择的时候,fragment A必须通知activity,然后activity通知fragment B,让它显示这篇文章。

  这个情况下,在fragment A中声明一个这样的接口OnArticleSelectedListener:

public static class FragmentA extends ListFragment {
...
// Container Activity must implement this interface
public interface OnArticleSelectedListener {
public void onArticleSelected(Uri articleUri);
}
...
}

  之后包含这个fragment的activity实现这个OnArticleSelectedListener接口,用覆写的onArticleSelected()方法将fragment A中发生的事通知fragment B。

  为了确保宿主activity实现这个接口,fragment A的onAttach() 方法(这个方法在fragment 被加入到activity中时由系统调用)中通过将传入的activity强制类型转换,实例化一个OnArticleSelectedListener对象:

public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
...
}

  如果activity没有实现这个接口,fragment将会抛出ClassCastException异常,如果成功了,mListener将会是activity实现OnArticleSelectedListener接口的一个引用,所以通过调用OnArticleSelectedListener接口的方法,fragment A可以和activity共享事件。

  比如,如果fragment A是ListFragment的子类,每一次用户点击一个列表项目,系统调用fragment中的onListItemClick() 方法,在这个方法中可以调用onArticleSelected()方法与activity共享事件。

public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Append the clicked item's row ID with the content provider Uri
Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
// Send the event and Uri to the host activity
mListener.onArticleSelected(noteUri);
}
...
}

处理Fragment的生命周期

三种停留状态

  管理fragment的生命周期和管理activity的生命周期类似,和activity一样,fragment可以在三种状态下停留:

  Resumed

  fragment在running的activity中可见。

  Paused

  另一个activity在前景运行,并且享有焦点,但是这个fragment所在的activity仍然可见(前景activity部分遮挡或者是半透明的)。

  Stopped

  fragment不可见。可能是因为宿主activity处于stopped状态,或者fragment被remove掉,然后加在了back stack中。

  一个处于stopped状态的activity还是存活状态的,所有的状态和成员信息会被系统保持。但是,它不再被用户可见,并且如果宿主activity被kill掉,它也会被kill掉。

数据存储和恢复

  和Activity类似,可以用Bundle类对象保存fragment的状态,当activity的进程被kill之后,需要重建activity时,可以用于恢复fragment的状态。

  存储时利用onSaveInstanceState()回调函数,恢复时是在 onCreate()onCreateView(), 或者onActivityCreated()里。

Back Stack

  activity和fragment生命周期最重要的不同之处是它们如何存储在各自的back stack中。

  Activity停止时,是存在一个由系统维护的back stack中,但是当fragment停止(被remove)时,需要程序员显示地调用addToBackStack() ,并且fragment是存在一个由宿主activity掌管的back stack中。

Fragment和Activity的生命周期

  宿主activity的声明周期直接影响到fragment的生命周期,比如activity生命周期的回调函数调用时,所有在其中的fragment的相同的回调函数会同时被调用。

  Fragment还有一些额外的生命周期回调函数:

onAttach()

  当fragment和activity被关联时调用。

onCreateView()

  当创建fragment的UI被初始化时调用。

onActivityCreated()

  当activity的onCreate()方法返回时调用。

onDestroyView()

  当fragment的UI被移除的时候调用。

onDetach()

  当fragment和activity去关联时调用。

如图:

  从这个图上可以看出activity的状态决定了fragment可能接收到的回调函数

  比如说,当activity接收到它的onCreate()回调函数,那么这个activity中的fragment最多接收到了onActivityCreated()。

  当activity处于Resumed状态时,可以自由地添加和移除fragment,也即是说,只有activity在Resumed状态时,fragment的状态可以独立改变。

  但是,当activity离开Resumed状态,fragment的生命周期被activity控制。

参考资料

  API Guides: Fragments

  http://developer.android.com/guide/components/fragments.html

【转】Fragment和Activity的更多相关文章

  1. Fragment 与Activity

    一个Activity 对应 多个Fragment; 每一个类 extends Fragment , 一个Activity 可以同时显示多个 Fragment; Fragment是依赖于Activity ...

  2. Fragment、Activity 保存状态

    Activity 保存状态1. void onCreate(Bundle savedInstanceState) 当Activity被第首次加载时执行.我们新启动一个程序的时候其主窗体的onCreat ...

  3. Fragment与Activity之间的通信

      我个人将Fragment与Activity间的通信比喻为JSP与Servlet间的通信,fragment中用接口的方式来进行与Activity的通信.通信的结果可以作为数据传入另一个Fragmen ...

  4. Android系列之Fragment(三)----Fragment和Activity之间的通信(含接口回调)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  5. 深入分析:Fragment与Activity交互的几种方式(一,使用Handler)

    这里我不再详细介绍那写比较常规的方式,例如静态变量,静态方法,持久化,application全局变量,收发广播等等. 首先我们来介绍使用Handler来实现Fragment与Activity 的交互. ...

  6. Fragment和Activity的区别

    Fragment用来描述一些行为或一部分用户界面在一个Activity中,可以合并多个Fragment在一个单独的Activity中建立多个UI面板,同时重用Fragment在多个activity中. ...

  7. Fragment 与 Activity 通信

    先说说背景知识: (From:http://blog.csdn.net/t12x3456/article/details/8119607) 尽管fragment的实现是独立于activity的,可以被 ...

  8. 安卓Fragment和Activity之间的数据通讯

    Fragment是Android3.0之后才推出来的.可以用来做底部菜单,现在很多APP都有用到这个底部菜单.当然TabHost也可以用来做底部菜单,但是Fragment来做,动画效果这些可以做得更炫 ...

  9. 关于Fragment与Fragment、Activity通信的四种方式

    一直想总结一下Fragment与Fragment.Activity通信的问题,今天有时间一共总结了三种,权当抛砖引玉,如果大家还有更好的方式来实现Fragment和Fragment.Activity的 ...

随机推荐

  1. IntelliJ IDEA14 和 Maven 系列:使用IntelliJ IDEA 14和Maven 7 创建java web项目(一)

    Intellij IDEA作为最好的Java IDE,创建Maven项目还是比较简单的,但是创建一个Maven Web项目还是要修改一些配置的,下面进行总结整理. 1前言 在创建项目中,IDEA提供了 ...

  2. 把传统的基于sql的企业信息中心迁移到spark 架构应该考虑的几点思考...[修改中]

    把传统的基于sql的企业信息中心迁移到spark 架构应该考虑的几点 * 理由: 赶时髦,  这还不够大条么? > 数据都设计为NO-SQL模式, 只有需要search的才建立2级索引. 就可以 ...

  3. /var子目录

    /var子目录 目录 描述 /var/log/message 日志信息,按周自动轮询 /var/spool/cron/root 定时器配置文件目录,默认按用户命名 /var/log/secure 记录 ...

  4. ubuntu thinkphp pathinfo 404等问题

    这个问题 困扰了我一天,由于对nginx的配置文件中的各种变量不懂.配置起来很麻烦,从网上搜索的,感觉合适自己的不多!!! 找啊找啊..终于找一篇!!!! 我的环境: php ubuntu 12.04 ...

  5. tomcat server.xml配置文件 解析

      把服务拆分出来了.      前几天我也进行了拆分.可是当时服务起不来所以我想会不会有什么设置,使得这个服务在主机中只能启一个.然后我又找了一台服务器,也把代码放了进去.结果仿佛是我料想到的样子, ...

  6. JS对于字符串的切割截取

    对于字符串的切割截取平时所用可能不是特别多,而且分的比较细,所以自备自查.有备无患. 由于之前所有均在一个demo测试,若是哪里打错了,敬请谅解.一些其余属性找时间继续添加. 1.函数:split() ...

  7. DOM 文档对象模型

    document 对象(作为对象),是 DOM 的核心作用:对内容,属性,样式等操作属性:title:设置/返回当前文档的标题url:返回当前文档的 urlinnerHTML:获取指定对象内的内容bg ...

  8. js中使用prototype扩展对象方法

    //---------------------对象 //1. var HomeContrl = function(){ this.foo = 'bar'; //对象方法 this.intro = fu ...

  9. rgba兼容IE系列

    在容器里面如果用到opacity或者filter:opacity里面的内容也会被滤镜化 如果不想里面的内容也被滤镜化我们可以用rgba来处理或者用透明的背景图片. 兼容ie的rgba的写法 backg ...

  10. Delphi接口

    program Demo1; { Create Date: 2014-06-29 Author: P.S.M 1.接口Demo1 } {$APPTYPE CONSOLE} uses SysUtils; ...