在某些案例中,可能需要Fragment與Activity共用事件。在Fragment內部定義一個回調介面是一個好方法,並且規定由持有它的Activity實現這個回調方法。當Activity通過介面接受回調時,它能在必要時與布局中的其他Fragment共用資訊。
例如,如果一個新聞類的應用程式在一個Activity中有兩個Fragment---一個用來顯示文章列表(Fragment A),另一個用來顯示文章內容(Fragment B)---然後再清單項目被選中時Fragment A必須告訴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。要確保持有Fragment的Activity實現這個介面, Fragment A 的onAttach()回調方法(當Fragment被添加到Activity時系統調用這個方法)通過類型轉換onAttach()傳入的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對象的引用,以便Fragment A能夠通過OnArticleSelectedListener介面定義的回調方法和Activity共用事件。例如,如果ListFragment繼承了Fragment A,那麼使用者每次點擊清單項目時,系統都會調用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);
}
...
}
傳遞給onListItemClick()的id參數是被點擊項目的行ID,Activity(或其他的Fragment)使用這個ID從應用程式的ContentProvider對象中擷取對應的文章。
關於使用有效內容提供器的更多內容,請看內容提供器(Content Providers)文檔。