在本節中,你會學到
1、定義接口
2、實現接口
3、將消息傳遞給fragment
為了重用Fragment UI 組件,在設計中你應該通過定義每一個fragemnt自己的layout和行為,讓fragment的自包含和模塊化。一旦你定義了這些可重用的Fragment,你可以通過Activity將它們關聯起來並通過程序的邏輯代碼將他們連接起來以實現整體組合的UI。
你會經常想要一個fragment與另一個fragment通信,例如基於用戶事件改變fragment中的內容。所有fragment質檢單額通信都是通過Activity關聯起來的。兩個fragment之間不應該直接進行通信。
定義接口
為了允許fragment和它的Activity通信,你應該fragment類中定義一個接口並在Activity中實現它。Fragment在onAttach()回調函數中獲取接口的具體實現的對象。后面,fragment就可以調用接口中的方法實現與Activity的通信。
下面是一個Fragment一Activity通信的例子:
// 用來存放fragment的Activtiy必須實現這個接口 public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // 這是為了保證Activity容器實現了用以回調的接口。如果沒有,它會拋出一個異常。 try { mCallback = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } }
現在fragment可以通過使用實現了OnHeadlineSelectedListener接口的mCallback實例
調用onArticleSelected()方法(或其他在接口中的方法)將消息傳遞給Activity。
例如下面在fragment中的方法將會在用戶點擊一個List item的時候被調用。這個fragment使用回調接口將時間傳遞給父Activtity。
@Override public void onListItemClick(ListView l, View v, int position, long id) { // 發送時間給Activity宿主 mCallback.onArticleSelected(position); }
實現接口
為了接收從fragment傳遞過來的事件回調,宿主Activity必須實現定義在fragment類中的接口。
例如,下面的activity實現了上個例子中的接口。
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // 用戶選擇了HeadlinesFragment中的頭標題后 // 做一些業務操作 } }
將消息傳遞給fragment
宿主Activity可以通過調用findFragmentById()方法獲取Fragment實例,然后直接調用Fragment的公有方法,將消息傳遞給Fragment。
例如,想象一下,之前講過的Activity可能包含有其他的fragment,而這些fragment通過上面的回調函數返回的接口動態地顯示一些內容。這種情況下,Activity可以將回調函數中接收到信息傳遞給需要的fragment。
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // 用戶選中HeadlinesFragment中的頭標題后 // 做一些必要的業務操作 ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // 如果 article frag 不為空,那么我們在同時顯示兩個fragmnet的布局中... // 調用ArticleFragment中的方法去更新它的內容 articleFrag.updateArticleView(position); } else { // 否則,我們就是在僅包含一個fragment的布局中並需要交換fragment... // 創建fragment並給他一個跟選中的文章有關的參數 ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // 用這個fragment替換任何在fragment_container中的東西 // 並添加事務到back stack中以便用戶可以回退到之前的狀態 transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // 提交事務 transaction.commit(); } } }