Fragment和Activity

Fragment和Activity的交互

  一個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的生命週期

三種停留狀態

  管理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

相關文章
相關標籤/搜索