轉自 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1016/441.html
首先,如果你想在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
<?xml version="1.0"encoding="utf-8"?><LinearLayout xmlns: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="vertical"> </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
<?xml version="1.0"encoding="utf-8"?><LinearLayout xmlns: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
<?xml version="1.0"encoding="utf-8"?><LinearLayout xmlns: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:
public class FirstActivity extends Activity implements MyListener { /** * 實現MyListener,當LeftFragment中點擊第一頁的時候,讓RightFragment顯示第一頁資訊,同理當點擊第二頁的時候,RightFragment顯示第二頁資訊 * * @param index * 顯示的頁數 */ public void 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 public void 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 protected void onResume() { super.onResume(); System.out.println("Activity--->onResume"); showMessageView = (TextView) findViewById(R.id.right_show_message); }}
LeftFragment:
public class LeftFragment extends Fragment { /** Acitivity要實現這個介面,這樣Fragment和Activity就可以共用事件觸發的資源了 */ public interface MyListener { public void showMessage(int index); } private MyListener myListener; private Button firstButton; private Button secondButton; private Button thirdButton; /** Fragment第一次附屬於Activity時調用,在onCreate之前調用 */ @Override public void onAttach(Activity activity) { super.onAttach(activity); System.out.println("LeftFragment--->onAttach"); myListener = (MyListener) activity; } @Override public void 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 public void 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 { public void 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:
public class RightFragment extends Fragment { @Override public void 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進行互動了.