標籤:列表 包括 wrap block art row group 異常 pause
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控制。
Android Fragment和Activity的互動介紹