API拾遺錄之Fragment


Fragment必須內嵌到activity中,它不能單獨使用,並且它的生命周期受到activity生命周期的制約——當activity暫停時,所有的fragment暫停,當activity停止時,所有的fragment停止。只有當activity處於運行態(resumed in lifecycle state)時,才可以單獨操作各個fragment,比如添加或刪除。在fragment事件中,activity管理着一個fragment返回棧。

在activity的layout中,fragment存在於activity的一個ViewGroup內。並且fragment定義了自己的view布局。有兩種方式添加fragment布局——一是在activity layout中使用<fragment>標簽。或者在代碼中添加到一個ViewGroup中。當然,fragment也可以以沒有UI的方式存在。

Creating a Fragment

創建一個Fragment的方法,同創建activity一樣,需要創建一個繼承自Fragment類或其子類的一個類,並實現onCreate(),onStart()等必要的回調方法。

Fragment生命周期和其對應的生命周期回調方法以及它和activity生命周期的關系圖如下:

同activity一樣,fragment也有三種存活狀態。

Resumed                       fragment在activity運行時處於可見位置

Paused                           另一個activity處於前台獲得焦點,但fragment所在的activity仍是可見的,未被完全覆蓋。

Stopped                          fragment完全不可見。出現這種情況有兩種可能,一是activity處於停止狀態,二是fragment從activity中刪除掉加入到返回棧中。一個停止態的fragment仍處於激活態(它的所有狀態和成員信息由系統保留)。

同activity一樣,當activity進程被系統殺死,重新創建fragment后,我們想恢復之前保存的狀態,做法是在onSaveInstanceState()中保存相關的數據,而在onCreate(),onCreateView()或者onActivityCreated()中恢復保存的數據。

當activity停止時,它被自動保存在一個由系統管理的返回棧中,用戶可以點擊返回按鈕回到這個activity。然而,fragment被保存在一個由activity管理的返回棧中,當去除fragment時,我們必須顯式的調用addToBackStack()才能把它保存在返回棧中。


fragment的生命周期受到activity生命周期的直接影響。比如,當activity接收onPause()時,該activity中的每個fragment都會接收onPause()。需要指出的是fragment中新有的幾個回調函數。

onAttach()                         fragment被綁定到activity時調用。

onCreateView()               創建fragment布局視圖時調用。

onActivityCreated()         當activity的onCreate()方法返回時調用。

onDestroyView()              fragment視圖刪除時調用。

onDetach()                        fragment從activity中解除綁定時調用。


Communicating with the Activity

盡管Fragment對象獨立於activity對象,它可以被使用於多個activity中,一個給定的fragment實例還是直接被綁定到包含它的activity實例中的。

在fragment中通過getActivity()可以獲取activity實例,然后與activity中的成員進行交互操作。

比如:

 

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


同樣的,activity可以通過FragmentManager獲取fragment的引用,例如:

 

 

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


Creating event callbacks to the activity

 

在一些實例中,可能需要fragment和activity共享events。一個好的方法是在fragment中定義回調接口,而在activity中實現它。當activity通過接口獲得回調時,它就可以與其它fragment在必要的時候共享信息。

例如:一個activity中有兩個fragment。一個顯示文章列表(fragment A),一個顯示具體的文章內容(fragment B)。A必須告知activity用戶選取了哪一篇文章,然后B從activity中獲知這一信息以顯示對應的文章內容。在這一實例中,OnArticleSelectedListener接口在A中聲明:

 

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

    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中我們需要實現這個OnArticleSelectedListener接口,並復寫onArticleSelected()函數通知B響應響應的事件。為了保證activity實現了這一接口,A的onAttach()回調初始化了OnArticleSelectedListener接口把activity傳遞過來。

 

Adding items to the Action Bar

通過onCreateOptionsMenu(),fragment可以為activity的Options Menu提供菜單項。為了確保這一方法成功實現回調。必須在onCreate()期間調用setHasOptionsMenu()告知Options Menu fragment要添加菜單項。

通過fragment添加的菜單會添加在已有菜單之后。選中菜單項時,fragment也會接收onOptionsItemSelected()回調。

通過registerForContextMenu()注冊,onCreateContextMenu()接收用戶打開信息,onContextItemSelected()接收用戶點擊信息可以實現Context Menu。

用戶點擊菜單的信息首先傳遞給activity,如果activity不處理,則傳遞給fragment。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM