android之Fragment(官網資料翻譯)三

 

與Activity通訊

儘管Fragment被實現爲一個獨立於Activity的對象,而且能夠在多個activity中使用,但一個給定的fragment實例是直接綁定到包含它的activity的. 特別的,fragment可使用 getActivity() 訪問Activity實例, 而且容易地執行好比在activity layout中查找一個view的任務ide

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

 一樣地,activity能夠經過從FragmentManager得到一個到Fragment的引用來調用fragment中的方法, 使用findFragmentById() 或 findFragmentByTag().函數

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

爲Activity建立事件回調方法

 

在一些狀況下, 你可能須要一個fragment與activity分享事件. 一個好的方法是在fragment中定義一個回調的interface, 並要求宿主activity實現它.當activity經過interface接收到一個回調, 必要時它能夠和在layout中的其餘fragment分享信息.
例如, 若是一個新的應用在activity中有2個fragment – 一個用來顯示文章列表(framgent A), 另外一個顯示文章內容(fragment B) – 而後 framgent A必須告訴activity什麼時候一個list item被選中,而後它能夠告訴fragmentB去顯示文章.
在這個例子中, OnArticleSelectedListener 接口在fragment A中聲明:
this

  
  
  
  
  1. public static class FragmentA extends ListFragment {  
  2.     ...  
  3.     // Container Activity must implement this interface  
  4.     public interface OnArticleSelectedListener {  
  5.         public void onArticleSelected(Uri articleUri);  
  6.    
  7.     }  
  8.     ...  

而後fragment的宿主activity實現 OnArticleSelectedListener 接口, 並覆寫 onArticleSelected() 來通知fragment B,從fragment A到來的事件.爲了確保宿主activity實現這個接口, fragment A的 onAttach() 回調方法(當添加fragment到activity時由系統調用) 經過將做爲參數傳入onAttach()的Activity作類型轉換來實例化一個OnArticleSelectedListener實例.spa

  
  
  
  
  1. public static class FragmentA extends ListFragment {  
  2.     OnArticleSelectedListener mListener;  
  3.     ...  
  4.     @Override 
  5.     public void onAttach(Activity activity) {  
  6.         super.onAttach(activity);  
  7.         try {  
  8.             mListener = (OnArticleSelectedListener) activity;  
  9.          } catch (ClassCastException e) {  
  10.             throw new ClassCastException(activity.toString() + " must implementOnArticleSelectedListener");  
  11.         }  
  12.     }  
  13.    
  14.     ...  
  15.    

若是activity沒有實現接口, fragment會拋出 ClassCastException 異常. 正常情形下,mListener成員會保持一個到activity的OnArticleSelectedListener實現的引用, 所以fragment A能夠經過調用在OnArticleSelectedListener接口中定義的方法分享事件給activity.例如, 若是fragment A是一個 ListFragment的子類, 每次用戶點擊一個列表項, 系統調用在fragment中的onListItemClick(),而後後者調用 onArticleSelected() 來分配事件給activity.對象

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

 傳給 onListItemClick() 的 id 參數是被點擊的項的行ID, activity(或其餘fragment)用來從應用的 ContentProvider 獲取文章.接口

添加項目到ActionBar

你的fragment能夠經過實現 onCreateOptionMenu() 提供菜單項給activity的選項菜單(以此類推, Action Bar也同樣).爲了使這個方法接收調用,不管如何, 你必須在 onCreate() 期間調用 setHasOptionsMenu() 來指出fragment願意添加item到選項菜單(不然, fragment將接收不到對 onCreateOptionsMenu()的調用).
隨後從fragment添加到Option菜單的任何項,都會被追加到現有菜單項的後面.當一個菜單項被選擇, fragment也會接收到 對 onOptionsItemSelected() 的回調.也能夠在你的fragment layout中經過調用registerForContextMenu() 註冊一個view來提供一個環境菜單.當用戶打開環境菜單, fragment接收到一個對 onCreateContextMenu() 的調用.當用戶選擇一個項目, fragment接收到一個對onContextItemSelected() 的調用.
注意: 儘管你的fragment會接收到它所添加的每個菜單項被選擇後的回調, 但實際上當用戶選擇一個菜單項時, activity會首先接收到對應的回調.若是activity的on-item-selected回調函數實現並無處理被選中的項目, 而後事件纔會被傳遞到fragment的回調.

這個規則適用於選項菜單和環境菜單.
生命週期

處理fragment的生命週期


管理fragment的生命週期, 大多數地方和管理activity生命週期很像.和activity同樣, fragment能夠處於3種狀態:
Resumed
在運行中的activity中fragment可見.
Paused
另外一個activity處於前臺並擁有焦點, 可是這個fragment所在的activity仍然可見(前臺activity局部透明或者沒有覆蓋整 個屏幕).
Stopped
要麼是宿主activity已經被中止, 要麼是fragment從activity被移除但被添加到後臺堆棧中.
中止狀態的fragment仍然活着(全部狀態和成員信息被系統保持着). 然而, 它對用戶再也不可見, 而且若是activity被幹掉, 他也會被幹掉.
進程

其對應關係圖以下:事件


 

和activity同樣, 你可使用Bundle保持fragment的狀態, 萬一activity的進程被幹掉,而且當activity被從新建立的時候, 你須要恢復fragment的狀態時就能夠用到. 你能夠在fragment的 onSaveInstanceState() 期間保存狀態, 並能夠在 onCreate(), onCreateView() 或 onActivityCreated() 期間恢復它.
生命週期方面activity和fragment之間最重要的區別是各自如何在它的後臺堆棧中儲存. 在默認狀況下, activity在中止後, 它會被放到一個由系統管理的用於保存activity的後臺堆棧.(所以用戶可使用BACK按鍵導航回退到它).
然而, 僅當你在一個事務期間移除fragment時,顯式調用addToBackStack()請求保存實例時,才被放到一個由宿主activity管理的後臺堆棧.
另外, 管理fragment的生命週期和管理activity生命週期很是相似.所以, "managing the activitylifecycle"中的相同實踐也一樣適用於fragment. 你須要理解的是, activity的生命如何影響fragment的生命.
事務

與activity生命週期的協調工做

fragment所生存的activity的生命週期,直接影響fragment的生命週期,每個activity的生命週期的回調行爲都會引發每個fragment中相似的回調.
例如,當activity接收到onPause()時,activity中的每個fragment都會接收到onPause().
Fragment 有一些額外的生命週期回調方法, 那些是處理與activity的惟一的交互,爲了執行例如建立和銷燬fragment的UI的動做. 這些額外的回調方法是:

  • onAttach()
    當fragment被綁定到activity時被調用(Activity會被傳入.).
  • onCreateView()
    建立和fragment關聯的view hierarchy時調用.
  • onActivityCreated()
    當activity的onCreate()方法返回時被調用.
  • onDestroyView()
    當和fragment關聯的view hierarchy正在被移除時調用.
  • onDetach()
    當fragment從activity解除關聯時被調用.

fragment生命週期的流程, 以及宿主activity對它的影響,在圖3中顯示.在這個圖中,能夠看到activity依次的每一個狀態是如何決定fragment可能接收到的回調方法.例如, 當activity接收到它的onCreate(),activity中的fragment接收到最可能是onActivityCreated(). 一旦activity到達了resumed狀態, 你能夠自由地在activity添加和移除fragment.所以,僅當activity處於resumed狀態時, fragment的生命週期才能夠獨立變化. 不管如何, 當activity離開resumed狀態,fragment再次被activity的推入它本身的生命週期過程.

相關文章
相關標籤/搜索