天天看點

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

Android Fragment完全解析,關于碎片你所需知道的一切

标簽: androidfragment布局平闆碎片 2013-05-07 09:33 198794人閱讀 評論(187) 收藏 舉報

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

分類: Android疑難解析(37)

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

版權聲明:本文出自郭霖的部落格,轉載必須注明出處。

轉載請注明出處:http://blog.csdn.net/guolin_blog/article/details/8881711

我們都知道,Android上的界面展示都是通過Activity實作的,Activity實在是太常用了,我相信大家都已經非常熟悉了,這裡就不再贅述。

但是Activity也有它的局限性,同樣的界面在手機上顯示可能很好看,在平闆上就未必了,因為平闆的螢幕非常大,手機的界面放在平闆上可能會有過分被拉長、控件間距過大等情況。這個時候更好的體驗效果是在Activity中嵌入"小Activity",然後每個"小Activity"又可以擁有自己的布局。是以,我們今天的主角Fragment登場了。

Fragment初探

為了讓界面可以在平闆上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常類似于Activity,可以像Activity一樣包含布局。Fragment通常是嵌套在Activity中使用的,現在想象這種場景:有兩個Fragment,Fragment 1包含了一個ListView,每行顯示一本書的标題。Fragment 2包含了TextView和ImageView,來顯示書的詳細内容和圖檔。

如果現在程式運作豎屏模式的平闆或手機上,Fragment 1可能嵌入在一個Activity中,而Fragment 2可能嵌入在另一個Activity中,如下圖所示:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

而如果現在程式運作在橫屏模式的平闆上,兩個Fragment就可以嵌入在同一個Activity中了,如下圖所示:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

由此可以看出,使用Fragment可以讓我們更加充分地利用平闆的螢幕空間,下面我們一起來探究下如何使用Fragment。

首先需要注意,Fragment是在3.0版本引入的,如果你使用的是3.0之前的系統,需要先導入android-support-v4的jar包才能使用Fragment功能。

建立一個項目叫做Fragments,然後在layout檔案夾下建立一個名為fragment1.xml的布局檔案:

[html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:background="#00ff00" >  
  5.     <TextView  
  6.         android:layout_width="wrap_content"  
  7.         android:layout_height="wrap_content"  
  8.         android:text="This is fragment 1"  
  9.         android:textColor="#000000"  
  10.         android:textSize="25sp" />  
  11. </LinearLayout>  

可以看到,這個布局檔案非常簡單,隻有一個LinearLayout,裡面加入了一個TextView。我們如法炮制再建立一個fragment2.xml :

[html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:background="#ffff00" >  
  5.     <TextView  
  6.         android:layout_width="wrap_content"  
  7.         android:layout_height="wrap_content"  
  8.         android:text="This is fragment 2"  
  9.         android:textColor="#000000"  
  10.         android:textSize="25sp" />  
  11. </LinearLayout>  

然後建立一個類Fragment1,這個類是繼承自Fragment的: [java] view plain copy

  1. public class Fragment1 extends Fragment {  
  2.     @Override  
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  4.         return inflater.inflate(R.layout.fragment1, container, false);  
  5.     }  
  6. }  

我們可以看到,這個類也非常簡單,主要就是加載了我們剛剛寫好的fragment1.xml布局檔案并傳回。同樣的方法,我們再寫好Fragment2 : [java] view plain copy

  1. public class Fragment2 extends Fragment {  
  2.     @Override  
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  4.         return inflater.inflate(R.layout.fragment2, container, false);  
  5.     }  
  6. }  

然後打開或建立activity_main.xml作為主Activity的布局檔案,在裡面加入兩個Fragment的引用,使用android:name字首來引用具體的Fragment: [html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:baselineAligned="false" >  
  5.     <fragment  
  6.         android:id="@+id/fragment1"  
  7.         android:name="com.example.fragmentdemo.Fragment1"  
  8.         android:layout_width="0dip"  
  9.         android:layout_height="match_parent"  
  10.         android:layout_weight="1" />  
  11.     <fragment  
  12.         android:id="@+id/fragment2"  
  13.         android:name="com.example.fragmentdemo.Fragment2"  
  14.         android:layout_width="0dip"  
  15.         android:layout_height="match_parent"  
  16.         android:layout_weight="1" />  
  17. </LinearLayout>  

最後打開或建立MainActivity作為程式的主Activity,裡面的代碼非常簡單,都是自動生成的: [java] view plain copy

  1. public class MainActivity extends Activity {  
  2.     @Override  
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_main);  
  6.     }  
  7. }  

現在我們來運作一次程式,就會看到,一個Activity很融洽地包含了兩個Fragment,這兩個Fragment平分了整個螢幕,效果圖如下:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

動态添加Fragment

你已經學會了如何在XML中使用Fragment,但是這僅僅是Fragment最簡單的功能而已。Fragment真正的強大之處在于可以動态地添加到Activity當中,是以這也是你必須要掌握的東西。當你學會了在程式運作時向Activity添加Fragment,程式的界面就可以定制的更加多樣化。下面我們立刻來看看,如何動态添加Fragment。

還是在上一節代碼的基礎上修改,打開activity_main.xml,将其中對Fragment的引用都删除,隻保留最外層的LinearLayout,并給它添加一個id,因為我們要動态添加Fragment,不用在XML裡添加了,删除後代碼如下:

[html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/main_layout"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:baselineAligned="false" >  
  6. </LinearLayout>  

然後打開MainActivity,修改其中的代碼如下所示: [java] view plain copy

  1. public class MainActivity extends Activity {  
  2.     @Override  
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_main);  
  6.         Display display = getWindowManager().getDefaultDisplay();  
  7.         if (display.getWidth() > display.getHeight()) {  
  8.             Fragment1 fragment1 = new Fragment1();  
  9.             getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit();  
  10.         } else {  
  11.             Fragment2 fragment2 = new Fragment2();  
  12.             getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit();  
  13.         }  
  14.     }  
  15. }  

首先,我們要擷取螢幕的寬度和高度,然後進行判斷,如果螢幕寬度大于高度就添加fragment1,如果高度大于寬度就添加fragment2。動态添加Fragment主要分為4步:

1.擷取到FragmentManager,在Activity中可以直接通過getFragmentManager得到。

2.開啟一個事務,通過調用beginTransaction方法開啟。

3.向容器内加入Fragment,一般使用replace方法實作,需要傳入容器的id和Fragment的執行個體。

4.送出事務,調用commit方法送出。

現在運作一下程式,效果如下圖所示:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

如果你是在使用模拟器運作,按下ctrl + F11切換到豎屏模式。效果如下圖所示:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

Fragment的生命周期

和Activity一樣,Fragment也有自己的生命周期,了解Fragment的生命周期非常重要,我們通過代碼的方式來瞧一瞧Fragment的生命周期是什麼樣的:

[java] view plain copy

  1. public class Fragment1 extends Fragment {  
  2.     public static final String TAG = "Fragment1";  
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  5.         Log.d(TAG, "onCreateView");  
  6.         return inflater.inflate(R.layout.fragment1, container, false);  
  7.     }  
  8.     @Override  
  9.     public void onAttach(Activity activity) {  
  10.         super.onAttach(activity);  
  11.         Log.d(TAG, "onAttach");  
  12.     }  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         Log.d(TAG, "onCreate");  
  17.     }  
  18.     @Override  
  19.     public void onActivityCreated(Bundle savedInstanceState) {  
  20.         super.onActivityCreated(savedInstanceState);  
  21.         Log.d(TAG, "onActivityCreated");  
  22.     }  
  23.     @Override  
  24.     public void onStart() {  
  25.         super.onStart();  
  26.         Log.d(TAG, "onStart");  
  27.     }  
  28.     @Override  
  29.     public void onResume() {  
  30.         super.onResume();  
  31.         Log.d(TAG, "onResume");  
  32.     }  
  33.     @Override  
  34.     public void onPause() {  
  35.         super.onPause();  
  36.         Log.d(TAG, "onPause");  
  37.     }  
  38.     @Override  
  39.     public void onStop() {  
  40.         super.onStop();  
  41.         Log.d(TAG, "onStop");  
  42.     }  
  43.     @Override  
  44.     public void onDestroyView() {  
  45.         super.onDestroyView();  
  46.         Log.d(TAG, "onDestroyView");  
  47.     }  
  48.     @Override  
  49.     public void onDestroy() {  
  50.         super.onDestroy();  
  51.         Log.d(TAG, "onDestroy");  
  52.     }  
  53.     @Override  
  54.     public void onDetach() {  
  55.         super.onDetach();  
  56.         Log.d(TAG, "onDetach");  
  57.     }  
  58. }  

可以看到,上面的代碼在每個生命周期的方法裡都列印了日志,然後我們來運作一下程式,可以看到列印日志如下:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

這時點選一下home鍵,列印日志如下:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

如果你再重新進入進入程式,列印日志如下:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

然後點選back鍵退出程式,列印日志如下:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

看到這裡,我相信大多數朋友已經非常明白了,因為這和Activity的生命周期太相似了。隻是有幾個Activity中沒有的新方法,這裡需要重點介紹一下:

  • onAttach方法:Fragment和Activity建立關聯的時候調用。
  • onCreateView方法:為Fragment加載布局時調用。
  • onActivityCreated方法:當Activity中的onCreate方法執行完後調用。
  • onDestroyView方法:Fragment中的布局被移除時調用。
  • onDetach方法:Fragment和Activity解除關聯的時候調用。

Fragment之間進行通信

通常情況下,Activity都會包含多個Fragment,這時多個Fragment之間如何進行通信就是個非常重要的問題了。我們通過一個例子來看一下,如何在一個Fragment中去通路另一個Fragment的視圖。

還是在第一節代碼的基礎上修改,首先打開fragment2.xml,在這個布局裡面添加一個按鈕:

[html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:orientation="vertical"  
  5.     android:background="#ffff00" >  
  6.     <TextView  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:text="This is fragment 2"  
  10.         android:textColor="#000000"  
  11.         android:textSize="25sp" />  
  12.     <Button   
  13.         android:id="@+id/button"  
  14.         android:layout_width="wrap_content"  
  15.         android:layout_height="wrap_content"  
  16.         android:text="Get fragment1 text"  
  17.         />  
  18. </LinearLayout>  

然後打開fragment1.xml,為TextView添加一個id: [html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:background="#00ff00" >  
  5.     <TextView  
  6.         android:id="@+id/fragment1_text"  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:text="This is fragment 1"  
  10.         android:textColor="#000000"  
  11.         android:textSize="25sp" />  
  12. </LinearLayout>  

接着打開Fragment2.java,添加onActivityCreated方法,并處理按鈕的點選事件: [java] view plain copy

  1. public class Fragment2 extends Fragment {  
  2.     @Override  
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  4.         return inflater.inflate(R.layout.fragment2, container, false);  
  5.     }  
  6.     @Override  
  7.     public void onActivityCreated(Bundle savedInstanceState) {  
  8.         super.onActivityCreated(savedInstanceState);  
  9.         Button button = (Button) getActivity().findViewById(R.id.button);  
  10.         button.setOnClickListener(new OnClickListener() {  
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 TextView textView = (TextView) getActivity().findViewById(R.id.fragment1_text);  
  14.                 Toast.makeText(getActivity(), textView.getText(), Toast.LENGTH_LONG).show();  
  15.             }  
  16.         });  
  17.     }  
  18. }  

現在運作一下程式,并點選一下fragment2上的按鈕,效果如下圖所示:

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切

我們可以看到,在fragment2中成功擷取到了fragment1中的視圖,并彈出Toast。這是怎麼實作的呢?主要都是通過getActivity這個方法實作的。getActivity方法可以讓Fragment擷取到關聯的Activity,然後再調用Activity的findViewById方法,就可以擷取到和這個Activity關聯的其它Fragment的視圖了。

好了,以上就是關于Fragment你所須知道的一切。如果想要切身體驗一下Fragment的實戰,請繼續閱讀 Android手機平闆兩不誤,使用Fragment實作相容手機和平闆的程式 以及 Android Fragment應用實戰,使用碎片向ActivityGroup說再見 。

第一時間獲得部落格更新提醒,以及更多技術資訊分享,歡迎關注我的微信公衆号,掃一掃下方二維碼或搜尋微信号guolin_blog,即可關注。

轉載::guolin專欄Android Fragment完全解析,關于碎片你所需知道的一切Android Fragment完全解析,關于碎片你所需知道的一切