本文譯自:http://developer.android.com/training/basics/fragments/communicating.html
為了重用Fragment的UI組件,你建立的每個Fragment都應該是自包含的、有它自己的布局和行為的模組化組件。一旦你定義了這些可重用的Fragment,你就可以把它們跟一個Activity關聯,並把它們跟應用程式的邏輯相連來實現全部的組合式UI。
你會經常想要一個Fragment跟另一個Fragment進行通訊,例如,要基於一個使用者事件來改變內容。所有的Fragment間的通訊都是通過跟關聯的Activity來完成的。另個Fragment不應該直接通訊。
定義介面
為了讓Fragment跟它的Activity通訊,你可以在Fragment類中定義一個介面,並在它所屬的Activity中實現該介面。Fragment在它的onAttach()方法執行期間捕獲該介面的實現,然後就可以調用介面方法,以便跟Activity通訊。
以下是Fragment跟Activity通訊的樣本:
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
現在,這個Fragment就可以通過調用OnHealdlineSelectedListener介面樣本mCallback的onArticleSelected()方法(或其他的介面中的方法)給Activity發送訊息。
例如,在Fragment中的下列方法會使用者點擊清單項目時被調用。該Fragment使用回調介面把該事件發送給它的父Activity。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
實現介面
為了從Fragment中接收事件回調,它的父Activity必須實現Fragment類中定義的介面。
例如,下面Activity實現了上面樣本中定義的介面:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
把訊息發送給一個Fragment
通過使用findFragmentById()方法捕獲Fragment執行個體,父Activity可以把訊息發送給該Fragment,然後直接調用該Fragment的公用方法。
例如,假設上面顯示的那個Activity包含了另外的用於顯示上面回調方法中返回的特定項目資料的Fragment。這種情況下,該Activity可以把回調方法中接收到資訊傳遞給顯示該項目的Fragment:
publicstaticclassMainActivityextendsActivity
implementsHeadlinesFragment.OnHeadlineSelectedListener{
...
publicvoid onArticleSelected(int position){
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag =(ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if(articleFrag !=null){
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
}else{
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment =newArticleFragment();
Bundle args =newBundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}