一个Fragment的实例老是和包含它的Activity直接相关。html
fragment能够经过getActivity()
方法来得到Activity的实例,而后就能够调用一些例如findViewById()之类的方法。java
如:android
View listView = getActivity().findViewById(R.id.list);程序员
可是注意调用getActivity()时,fragment必须和activity关联(attached to an activity),不然将会返回一个null。app
类似的,activity也能够得到一个fragment的引用,从而调用fragment中的方法。ide
得到fragment的引用要用FragmentManager,以后能够调用findFragmentById()
或者 findFragmentByTag()
.函数
好比:布局
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);ui
一些状况下,可能须要fragment和activity共享事件,一个比较好的作法是在fragment里面定义一个回调接口,而后要求宿主activity实现它。this
当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的生命周期和管理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还有一些额外的生命周期回调函数:
当fragment和activity被关联时调用。
当建立fragment的UI被初始化时调用。
当activity的onCreate()方法返回时调用。
当fragment的UI被移除的时候调用。
当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