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這些介面
fragment和activity的回撥機制又是OOP的一次完美演繹!
下面通過一個例子來說明:
我把Activity的UI分為兩個部分,左邊和右邊,左邊用來放置點選的按鈕(LeftFragment),右邊用來放置對應點選後顯示的資訊(RightFragment).
Activity的佈局layout檔案:main.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal">
- <LinearLayout
- android:id="@+id/left_layout"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:orientation
- </LinearLayout>
- <LinearLayout
- android:id="@+id/right_layout"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="10"
- android:orientation="vertical">
- </LinearLayout>
- </LinearLayout>
LeftFragment的佈局layout:leftfragment.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <Button
- android:id="@+id/first_button"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/first_button"/>
- <Button
- android:id="@+id/second_button"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/second_button"/>
- <Button
- android:id="@+id/third_button"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/third_button"/>
- </LinearLayout>
RightFragment的佈局layout:rightfragment.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <TextView
- android:id="@+id/right_show_message"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/holo_orange_dark"
- android:textColor="@android:color/white"/>
- </LinearLayout>
以上是兩個fragment和一個Activity的佈局檔案,下面來看他們的java檔案
Activity:
- publicclass FirstActivity extends Activity implements MyListener
- {
- /**
- * 實現MyListener,當LeftFragment中點選第一頁的時候,讓RightFragment顯示第一頁資訊,同理當點選第二頁的時候,RightFragment顯示第二頁資訊
- *
- * @param index
- * 顯示的頁數
- */
- publicvoid showMessage(int index)
- {
- if(1 == index)
- showMessageView.setText(R.string.first_page);
- if(2 == index)
- showMessageView.setText(R.string.second_page);
- if(3 == index)
- showMessageView.setText(R.string.third_page);
- }
- /** 得到RightFragment中顯示資訊的控制元件 */
- private TextView showMessageView;
- /** Called when the activity is first created. */
- @Override
- publicvoid onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("Activity--->onCreate");
- FragmentManager manager = getFragmentManager();
- FragmentTransaction transaction = manager.beginTransaction();
- // 動態增加Fragment
- RightFragment rightFragment = newRightFragment();
- LeftFragment leftFragment = newLeftFragment();
- transaction.add(R.id.left_layout, leftFragment, "leftfragment");
- transaction.add(R.id.right_layout, rightFragment, "rightfragment");
- transaction.commit();
- }
- @Override
- protectedvoid onResume()
- {
- super.onResume();
- System.out.println("Activity--->onResume");
- showMessageView = (TextView) findViewById(R.id.right_show_message);
- }
- }
LeftFragment:
- publicclass LeftFragment extends Fragment
- {
- /** Acitivity要實現這個介面,這樣Fragment和Activity就可以共享事件觸發的資源了 */
- publicinterface MyListener
- {
- publicvoid showMessage(int index);
- }
- private MyListener myListener;
- private Button firstButton;
- private Button secondButton;
- private Button thirdButton;
- /** Fragment第一次附屬於Activity時呼叫,在onCreate之前呼叫 */
- @Override
- publicvoid onAttach(Activity activity)
- {
- super.onAttach(activity);
- System.out.println("LeftFragment--->onAttach");
- myListener = (MyListener) activity;
- }
- @Override
- publicvoid onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- System.out.println("LeftFragment--->onCreate");
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- System.out.println("LeftFragment--->onCreateView");
- returninflater.inflate(R.layout.leftfragment, container, false);
- }
- @Override
- publicvoid onResume()
- {
- super.onResume();
- System.out.println("LeftFragment--->onResume");
- firstButton = (Button) getActivity().findViewById(R.id.first_button);
- secondButton = (Button) getActivity().findViewById(R.id.second_button);
- thirdButton = (Button) getActivity().findViewById(R.id.third_button);
- MyButtonClickListener clickListener = newMyButtonClickListener();
- firstButton.setOnClickListener(clickListener);
- secondButton.setOnClickListener(clickListener);
- thirdButton.setOnClickListener(clickListener);
- }
- /** 按鈕的監聽器 */
- class MyButtonClickListener implements OnClickListener
- {
- publicvoid onClick(View v)
- {
- Button button = (Button) v;
- if(button == firstButton)
- myListener.showMessage(1);
- if(button == secondButton)
- myListener.showMessage(2);
- if(button == thirdButton)
- myListener.showMessage(3);
- }
- }
- }
RightFragment:
- publicclass RightFragment extends Fragment
- {
- @Override
- publicvoid onCreate(Bundle savedInstanceState)
- {
- System.out.println("RightFragment--->onCreate");
- super.onCreate(savedInstanceState);
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
- {
- System.out.println("RightFragment--->onCreateView");
- returninflater.inflate(R.layout.rightfragment, container, false);
- }
- }
注意,Fragment的生命週期和Activity生命週期之間的關係。在Activity裡動態生成Fragment,首先是Activity呼叫onCreate()方法,但是這時候還沒有載入到Fragment裡的元件,當Fragment呼叫其onCreateView()方法後,Activity才能得到Fragment中的元件
這裡最關鍵的就是Fragment要有一個介面和這個介面的引用,而這個介面需要Activity去實現它。當Fragment呼叫onAttach(Activity acitivity)方法的時候,將這個activity傳遞給這個介面引用,這樣,就可以和Activity進行互動了.