Android_Fragment_Fragment詳解

目錄(?)[+]

1.Fragment概述

在一個Activity中, Fragment代表UI的一個部分或者一個行爲。一個Activity可以結合多個Fragment對象,也可以在多個activity中使用相同Fragment字節碼對應的不同對象。一個Fragment對象必須被嵌入在一個主Activity對象中,該Fragment的生命週期與主Activity息息相關。比如,當主Activity處於paused狀態,其對應的所有Fragment對象均處於paused狀態,只有當主Activity處於resumed狀態時,Fragment才能處於自由控制狀態。

2.創建Fragment

爲了創建一個Fragment,應該去繼承Fragment或者其子類,覆寫相應的方法。比如onCreate(),OnCreateView(),onPause()等等

實例化一個Fragment對象,除了可以new外,還可以使用Fragment的靜態函數Fragment.instantiate(mContext, "class 完整路徑", info.args);,利用反射實現,但是性能較低

(1).添加UI界面

爲該Fragment展現一個佈局,必須去實現onCreateView()回掉方法。
注意:當該Fragment繼承了ListFragment時,不需要覆寫onCreateView()方法,因爲默認返回一個ListView對象

[java] view plain copy
  1. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  2.         Bundle savedInstanceState) {  
  3.     View view = inflater.inflate(R.layout.list, null);  
  4.     return view;  
  5. }  

(2).添加Fragment到Activity

1).通過layout佈局文件

android:name屬性應該爲Fragment對應類的完整路徑。

[html] view plain copy
  1. <fragment  
  2.     android:id="@+id/f"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:name="com.example.a29fragment.MyFragment"/>  
在兼容低版本時,如果使用靜態註冊,而MyFragment是使用了兼容support.v4.app.Fragment,就不能使用Activity了,只能使用FragmentActivity

fragment靜態在xml文件配置,該fragment不能被移除,不可動態被編輯。

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal" >  
  6.   
  7.     <fragment  
  8.         android:id="@+id/list"  
  9.         android:name="com.example.news.ArticleListFragment"  
  10.         android:layout_width="0dp"  
  11.         android:layout_height="match_parent"  
  12.         android:layout_weight="1" />  
  13.     <fragment  
  14.         android:id="@+id/viewer"  
  15.         android:name="com.example.news.ArticleReaderFragment"  
  16.         android:layout_width="0dp"  
  17.         android:layout_height="match_parent"  
  18.         android:layout_weight="2" />  
  19.   
  20. </LinearLayout>  

2).通過Java代碼

當Activity運行時,可以自由的在該activity上添加fragment對象,但應該指定一個ViewGroup容器,可以FragmentTransaction完成fragment的添加移除或者替換。

[java] view plain copy
  1. manager = getFragmentManager();  
  2. if(manager.findFragmentByTag("right") == null){  
  3.     manager.beginTransaction().replace(R.id.right, new RightFrag(), "right").commit();  
  4. }  

(3).fragment唯一標示符

每個fragment需要定義一個唯一的標識符,如果activity被銷燬又重新啓動,系統能夠恢復該fragment的狀態。如果想重新恢復,需滿足下面有3種方式之一:

1).定義ID

在佈局文件中,定義android:id屬性

[html] view plain copy
  1. <fragment  
  2.     android:id="@+id/list"  
  3.     android:name="com.example.news.ArticleListFragment"  
  4.     android:layout_width="0dp"  
  5.     android:layout_height="match_parent"  
  6.     android:layout_weight="1" />  

2).指明tag

android:tag 指明 或者 一個fragment對象add()或者replace()時指定tag

[html] view plain copy
  1. <fragment  
  2.     android:id="@+id/list"  
  3.     android:tag="first"  
  4.     android:name="com.example.news.ArticleListFragment"  
  5.     android:layout_width="0dp"  
  6.     android:layout_height="match_parent"  
  7.     android:layout_weight="1" />  

或者

[java] view plain copy
  1. manager.beginTransaction()  
  2.     .replace(R.id.right, new RightFrag(), "right")//在事務中指明該fragment的tag  
  3. .commit();  

3).viewgroup ID

如果該fragment均沒有id和tag,系統將使用container view佈局的id

3.Fragment的管理

通過getFragmentManager()方法,可以得到FragmentManager對象,主要完成下面的功能

[java] view plain copy
  1. FragmentManager manager = getFragmentManager();  

(1).得到已經存在Fragment對象

如果該fragment在佈局文件中指定了id,通過findFragmentById()得到對象,或者指定了tag可以通過findFragmentByTag()得到對象

[java] view plain copy
  1. Fragment fragment = getFragmentManager().findFragmentByTag("right");  
  2. //or  
  3. Fragment fragment = getFragmentManager().findFragmentById(id);  

(2).註冊OnBackStackChangedListener監聽器

可以用來監聽該任務對應的返回棧信息,當該返回棧狀態發生改變時,執行對應的onBackStackChanged() 方法

[java] view plain copy
  1. manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {  
  2.     @Override  
  3.     public void onBackStackChanged() {  
  4.         Toast.makeText(MainActivity.this"返回堆狀態發生改變"1).show();  
  5.     }  
  6. });  

(3).彈出返回棧

模擬用戶點擊返回鍵,將指定的fragment從返回棧中彈出,該操作爲異步的。前提是該fragment對象使用.beginTransaction().addToBackStack("right")添加了進返回棧

[java] view plain copy
  1. manager.popBackStack(); //Pop the top state off the back stack  

(4).FragmentTransaction事務

事務主要包含一些操作的集合,比如增加移除替換,動畫設置等等

[html] view plain copy
  1. /*  
  2.  * 通過manager開啓一個事務,該事務包含一些操作的集合,通事務可以 add(), remove(), replace()  
  3.  * 完成對Fragment的操作,並使用commit()提交  
  4.  */  
  5. FragmentTransaction transaction = manager.beginTransaction();  
  6.   
  7. transaction.replace(R.id.right, new RightFrag(), "right");  
  8. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);//設置動畫  
  9. transaction.addToBackStack("right"); // 將該fragment加入返回堆  
  10. // 提交事務  
  11. transaction.commit();  

(5).Fragment狀態管理

[java] view plain copy
  1. /* 
  2.  * 管理Fragment的狀態 
  3.  *  如果在一個主activityViewGroup中添加一個fragment, 
  4.  *  如果手機屏幕旋轉了,當前activity被銷燬重建,fragment也被activityManager創建 
  5.  *  故在onCreate中,需要判斷一下 
  6.  */  
  7. @Override  
  8. protected void onCreate(Bundle savedInstanceState) {  
  9.     super.onCreate(savedInstanceState);  
  10.     setContentView(R.layout.activity_main);  
  11.     manager = getFragmentManager();  
  12.     if (manager.findFragmentByTag("right") == null) {  
  13.         // if(savedInstanceState == null)也可判斷該fragment是否已經加載  
  14.   
  15.         manager.beginTransaction()  
  16.             .replace(R.id.right, new RightFrag(), "right")  
  17.             .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)// 設置動畫  
  18.             .addToBackStack("right"// 將該fragment加入返回堆  
  19.         // 提交事務  
  20.         .commit();  
  21.     }  
  22. }  

4.向下兼容

可參閱CursorLoader的兼容~~,特別注意:如果使用靜態註冊,在佈局文件配置<fragment>標籤時,指定了name的class由於兼容support.v4.app.Fragment,加載佈局文件的Class就不能繼承Activity了,只能繼承FragmentActivity

5.Fragment間信息交互

(1).取得對象

[java] view plain copy
  1. /* 
  2.  * 點擊該Fragment的button按鈕,將該button的text設置爲另一個fragment中Edittext的文本值 
  3.  */  
  4. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.         Bundle savedInstanceState) {  
  6.     View view = inflater.inflate(R.layout.list, null);  
  7.     final Button button = (Button) view.findViewById(R.id.confirm);  
  8.     button.setOnClickListener(new View.OnClickListener() {  
  9.           
  10.         @Override  
  11.         public void onClick(View v) {  
  12.             //通過FragmentManager找到另一個fragment中的edittext對象,並取得text內容  
  13.             EditText editText = (EditText)(getFragmentManager().findFragmentByTag("left").getView().findViewById(R.id.name));  
  14.             button.setText(editText.getText().toString());  
  15.         }  
  16.     });  
  17.     return view;  
  18. }  

 (2).通回掉函數

[java] view plain copy
  1. public class MainActivity extends Activity {  
  2.     private FragmentManager manager;  
  3.     private Button button;  
  4.   
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.           
  10.         button.setOnClickListener(new View.OnClickListener() {  
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 RightFragment rightFrag = (RightFragment) (getFragmentManager().findFragmentByTag("right"));  
  14.                 /* 
  15.                  * 通過set方法,向其傳遞一個實例化對象,由於rightFrag.set()方法內部執行RightFragment.CallBack.get()方法,完成了參數的傳遞 
  16.                  */  
  17.                 rightFrag.set(new RightFragment.CallBack() {  
  18.                     @Override  
  19.                     public void get(String str) {  
  20.                         button.setText(str);  
  21.                     }  
  22.                 });  
  23.             }  
  24.         });  
  25.     }  
  26.   
  27. }  
[java] view plain copy
  1. public class RightFragment extends ListFragment {  
  2.     private LoaderManager manager;  
  3.   
  4.     @Override  
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         manager = getLoaderManager();  
  8.     }  
  9.   
  10.     /* 
  11.      * 點擊該Fragment的button按鈕,將該button的text設置爲另一個fragment中Edittext的文本值 
  12.      */  
  13.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  14.             Bundle savedInstanceState) {  
  15.         View view = inflater.inflate(R.layout.list, null);  
  16.         return view;  
  17.     }  
  18.   
  19.     /** 
  20.      * 通過調用該方法,接收一個回掉函數對象,callBack.get(str); 
  21.      * @param callBack 
  22.      */  
  23.     public void set(CallBack callBack) {  
  24.         EditText editText = (EditText) getView().findViewById(R.id.name);  
  25.         callBack.get(editText.getText().toString());  
  26.     }  
  27.   
  28.     /* 
  29.      * 回掉接口 
  30.      */  
  31.     interface CallBack {  
  32.         public void get(String str);  
  33.     }  
  34. }  

6.Fragment的生命週期

(1).生命週期路線圖

生命狀態

週期過程

 

foreground lifetime

onResume(A)

onResume(F)

onPause(F)

onPause(A)

visible lifetime

onCreateView(F)

onActivityCreated(F)

onStart(A)

onStart(F)

onResume(A)

onResume(F)

onPause(F)

onPause(A)

onStop(F)

onStop(A)

onDestroyView(F)

entire lifetime

完整的生命週期

 (2).生命週期回掉函數概述

方法 描述
onAttach(Activity)

當前Fragment與Activity關聯,調用!

onCreate()

完成fragment的初始化創建

  onCreateView()

創建並返回與當前fragment相關聯的層次視圖view

  onActivityCreated()

主activity的onCreate()執行完後,該方法才執行

  onStart()

fragment可見,當主activity處於started狀態後執行

    onResume()

fragment能與用戶交互,當主activity處於resumed狀態後執行

    onPause()

fragment不在與用戶交互,可能在主activity將要處於paused前執行,可能該fragment被修改

  onStop()

fragment不在可見,可能在主activity將要處於stopped前執行,可能該fragment被修改

  onDestroyView()

允許該fragment清理視圖相關資源

onDestroy()

清理掉視圖state信息

onDetach()

該fragment不在於activity關聯

 

發佈了22 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章