1. 程式人生 > >android中fragment與activity之間通訊原理以及例子

android中fragment與activity之間通訊原理以及例子

首先,如果你想在android3.0及以下版本使用fragment,你必須引用android-support-v4.jar這個包

然後你寫的activity不能再繼承自Activity類了,而是要繼承android.support.v4.app.FragmentActivity,一些其他的父類也有相應的變化.

由於在android的實現機制中fragment和activity會被分別例項化為兩個不相干的物件,他們之間的聯絡由activity的一個成員物件fragmentmanager來維護.fragment例項化後會到activity中的fragmentmanager去註冊一下,這個動作封裝在fragment物件的onAttach中,所以你可以在fragment中宣告一些回撥介面,當fragment呼叫onAttach時,將這些回撥介面例項化,這樣fragment就能呼叫各個activity的成員函數了,當然activity必須implements這些介面

,否則會包classcasterror

fragment和activity的回撥機制又是OOP的一次完美演繹!

下面通過一個例子來說明:

我把Activity的UI分為兩個部分,左邊和右邊,左邊用來放置點選的按鈕(LeftFragment),右邊用來放置對應點選後顯示的資訊(RightFragment).

Activity的佈局layout檔案:main.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent"
  5.     android:orientation="horizontal">
  6.     <LinearLayout
  7.         android:id="@+id/left_layout"
  8.         android:layout_width="wrap_content"
  9.         android:layout_height="fill_parent"
  10.         android:layout_weight="1"
  11.         android:orientation
    ="vertical">
  12.     </LinearLayout>
  13.     <LinearLayout
  14.         android:id="@+id/right_layout"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="fill_parent"
  17.         android:layout_weight="10"
  18.         android:orientation="vertical">
  19.     </LinearLayout>
  20. </LinearLayout>

LeftFragment的佈局layout:leftfragment.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical">
  6.     <Button
  7.         android:id="@+id/first_button"
  8.         android:layout_width="fill_parent"
  9.         android:layout_height="wrap_content"
  10.         android:text="@string/first_button"/>
  11.     <Button
  12.         android:id="@+id/second_button"
  13.         android:layout_width="fill_parent"
  14.         android:layout_height="wrap_content"
  15.         android:text="@string/second_button"/>
  16.     <Button
  17.         android:id="@+id/third_button"
  18.         android:layout_width="fill_parent"
  19.         android:layout_height="wrap_content"
  20.         android:text="@string/third_button"/>
  21. </LinearLayout>


RightFragment的佈局layout:rightfragment.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical">
  6.     <TextView
  7.         android:id="@+id/right_show_message"
  8.         android:layout_width="fill_parent"
  9.         android:layout_height="fill_parent"
  10.         android:background="@android:color/holo_orange_dark"
  11.         android:textColor="@android:color/white"/>
  12. </LinearLayout>


以上是兩個fragment和一個Activity的佈局檔案,下面來看他們的java檔案

Activity:

  1. publicclass FirstActivity extends Activity implements MyListener   
  2. {  
  3.     /** 
  4.      * 實現MyListener,當LeftFragment中點選第一頁的時候,讓RightFragment顯示第一頁資訊,同理當點選第二頁的時候,RightFragment顯示第二頁資訊 
  5.      *  
  6.      * @param index  
  7.      *            顯示的頁數  
  8.      */
  9.     publicvoid showMessage(int index)   
  10.     {  
  11.         if(1 == index)   
  12.             showMessageView.setText(R.string.first_page);  
  13.         if(2 == index)   
  14.             showMessageView.setText(R.string.second_page);  
  15.         if(3 == index)   
  16.             showMessageView.setText(R.string.third_page);  
  17.     }  
  18.     /** 得到RightFragment中顯示資訊的控制元件 */
  19.     private TextView showMessageView;   
  20.     /** Called when the activity is first created. */
  21.     @Override
  22.     publicvoid onCreate(Bundle savedInstanceState)   
  23.     {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.main);  
  26.         System.out.println("Activity--->onCreate");  
  27.         FragmentManager manager = getFragmentManager();   
  28.         FragmentTransaction transaction = manager.beginTransaction();   
  29.         // 動態增加Fragment 
  30.         RightFragment rightFragment = newRightFragment();   
  31.         LeftFragment leftFragment = newLeftFragment();   
  32.         transaction.add(R.id.left_layout, leftFragment, "leftfragment");  
  33.         transaction.add(R.id.right_layout, rightFragment, "rightfragment");  
  34.         transaction.commit();  
  35.     }  
  36.     @Override
  37.     protectedvoid onResume()   
  38.     {  
  39.         super.onResume();  
  40.         System.out.println("Activity--->onResume");  
  41.         showMessageView = (TextView) findViewById(R.id.right_show_message);   
  42.     }  
  43. }  


LeftFragment:

  1. publicclass LeftFragment extends Fragment   
  2. {  
  3.     /** Acitivity要實現這個介面,這樣Fragment和Activity就可以共享事件觸發的資源了 */
  4.     publicinterface MyListener   
  5.     {  
  6.         publicvoid showMessage(int index);   
  7.     }  
  8.     private MyListener myListener;   
  9.     private Button firstButton;   
  10.     private Button secondButton;   
  11.     private Button thirdButton;   
  12.     /** Fragment第一次附屬於Activity時呼叫,在onCreate之前呼叫 */
  13.     @Override
  14.     publicvoid onAttach(Activity activity)   
  15.     {  
  16.         super.onAttach(activity);  
  17.         System.out.println("LeftFragment--->onAttach");  
  18.         myListener = (MyListener) activity;   
  19.     }  
  20.     @Override
  21.     publicvoid onCreate(Bundle savedInstanceState)   
  22.     {  
  23.         super.onCreate(savedInstanceState);  
  24.         System.out.println("LeftFragment--->onCreate");  
  25.     }  
  26.     @Override
  27.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
  28.     {  
  29.         System.out.println("LeftFragment--->onCreateView");  
  30.         returninflater.inflate(R.layout.leftfragment, container, false);  
  31.     }  
  32.     @Override
  33.     publicvoid onResume()   
  34.     {  
  35.         super.onResume();  
  36.         System.out.println("LeftFragment--->onResume");  
  37.         firstButton = (Button) getActivity().findViewById(R.id.first_button);   
  38.         secondButton = (Button) getActivity().findViewById(R.id.second_button);   
  39.         thirdButton = (Button) getActivity().findViewById(R.id.third_button);   
  40.         MyButtonClickListener clickListener = newMyButtonClickListener();   
  41.         firstButton.setOnClickListener(clickListener);  
  42.         secondButton.setOnClickListener(clickListener);  
  43.         thirdButton.setOnClickListener(clickListener);  
  44.     }  
  45.     /** 按鈕的監聽器 */
  46.     class MyButtonClickListener implements OnClickListener   
  47.     {  
  48.         publicvoid onClick(View v)   
  49.         {  
  50.             Button button = (Button) v;   
  51.             if(button == firstButton)   
  52.                 myListener.showMessage(1);  
  53.             if(button == secondButton)   
  54.                 myListener.showMessage(2);  
  55.             if(button == thirdButton)   
  56.                 myListener.showMessage(3);  
  57.         }  
  58.     }  
  59. }  


RightFragment:

  1. publicclass RightFragment extends Fragment   
  2. {  
  3.     @Override
  4.     publicvoid onCreate(Bundle savedInstanceState)   
  5.     {  
  6.         System.out.println("RightFragment--->onCreate");  
  7.         super.onCreate(savedInstanceState);  
  8.     }  
  9.     @Override
  10.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
  11.     {  
  12.         System.out.println("RightFragment--->onCreateView");  
  13.         returninflater.inflate(R.layout.rightfragment, container, false);  
  14.     }  
  15. }  


注意,Fragment的生命週期和Activity生命週期之間的關係。在Activity裡動態生成Fragment,首先是Activity呼叫onCreate()方法,但是這時候還沒有載入到Fragment裡的元件,當Fragment呼叫其onCreateView()方法後,Activity才能得到Fragment中的元件

這裡最關鍵的就是Fragment要有一個介面和這個介面的引用,而這個介面需要Activity去實現它。當Fragment呼叫onAttach(Activity acitivity)方法的時候,將這個activity傳遞給這個介面引用,這樣,就可以和Activity進行互動了.