1. 程式人生 > >Android Fragment 詳解

Android Fragment 詳解

Fragment產生原因:

同時適配手機和平板、UI和邏輯的共享。

介紹:
  • Fragment也會被加入回退棧中。
  • Fragment擁有自己的生命週期和接受、處理使用者的事件。
  • 可以動態的新增、替換和移除某個Fragment。
  • 必須依存於Activity
生命週期


Fragment依附於Activity的生命狀態


Fragment生命週期方法含義:

public void onAttach(Context context)

onAttach方法會在Fragment於視窗關聯後立刻呼叫。從該方法開始,就可以通過Fragment.getActivity方法獲取與Fragment關聯的視窗物件,但因為Fragment的控制元件未初始化,所以不能夠操作控制元件。

public void onCreate(Bundle savedInstanceState)

在呼叫完onAttach執行完之後立刻呼叫onCreate方法,可以在Bundle物件中獲取一些在Activity中傳過來的資料。通常會在該方法中讀取儲存的狀態,獲取或初始化一些資料。在該方法中不要進行耗時操作,不然視窗不會顯示。

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)

該方法是Fragment很重要的一個生命週期方法,因為會在該方法中建立在Fragment顯示的View,其中inflater是用來裝載佈局檔案的,container是<fragment>

標籤的父標籤對應物件,savedInstanceState引數可以獲取Fragment儲存的狀態,如果未儲存那麼就為null。

public void onViewCreated(View view,Bundle savedInstanceState)

Android在建立完Fragment中的View物件之後,會立刻回撥該方法。其種view引數就是onCreateView中返回的view,而bundle物件用於一般用途。

public void onActivityCreated(Bundle savedInstanceState)

在Activity的onCreate方法執行完之後,Android系統會立刻呼叫該方法,表示視窗已經初始化完成,從這一個時候開始,就可以在Fragment中使用getActivity().findViewById(Id);來操控Activity中的view了。

public void onStart()

這個沒啥可講的,但有一個細節需要知道,當系統呼叫該方法的時候,fragment已經顯示在ui上,但還不能進行互動,因為onResume方法還沒執行完。

public void onResume()

該方法為fragment從建立到顯示Android系統呼叫的最後一個生命週期方法,呼叫完該方法時候,fragment就可以與使用者互動了。

public void onPause()

fragment由活躍狀態變成非活躍狀態執行的第一個回撥方法,通常可以在這個方法中儲存一些需要臨時暫停的工作。如儲存音樂播放進度,然後在onResume中恢復音樂播放進度。

public void onStop()

當onStop返回的時候,fragment將從螢幕上消失。

public void onDestoryView()

該方法的呼叫意味著在 onCreateView 中建立的檢視都將被移除。

public void onDestroy()

Android在Fragment不再使用時會呼叫該方法。

public void onDetach()

為Fragment生命週期中的最後一個方法,當該方法執行完後,Fragment與Activity不再有關聯。

Fragment與Activity之間的互動

Fragment與Activity之間的互動可以通過Fragment.setArguments(Bundle args)以及Fragment.getArguments()來實現。

Fragment狀態的持久化

方法一:

可以通過protected void onSaveInstanceState(Bundle outState),protected void onRestoreInstanceState(Bundle savedInstanceState) 狀態儲存和恢復的方法將狀態持久化。

方法二:

我們只需要將Fragment在Activity中作為一個變數整個儲存,只要儲存了Fragment,那麼Fragment的狀態就得到儲存了。

  • FragmentManager.putFragment(Bundle bundle, String key, Fragment fragment) 是在Activity中儲存Fragment的方法。
  • FragmentManager.getFragment(Bundle bundle, String key) 是在Activity中獲取所儲存的Frament的方法。

很顯然,key就傳入Fragment的id,fragment就是你要儲存狀態的fragment,但,我們注意到上面的兩個方法,第一個引數都是Bundle,這就意味著FragmentManager是通過Bundle去儲存Fragment的。但是,這個方法僅僅能夠儲存Fragment中的控制元件狀態,比如說EditText中使用者已經輸入的文字(注意!在這裡,控制元件需要設定一個id,否則Android將不會為我們儲存控制元件的狀態),而Fragment中需要持久化的變數依然會丟失,但依然有解決辦法,就是利用方法一!

下面給出狀態持久化的事例程式碼:

/** Activity中的程式碼 **/
 	 FragmentB fragmentB;

     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fragment_activity);
         if( savedInstanceState != null ){
             fragmentB = (FragmentB) getSupportFragmentManager().getFragment(savedInstanceState,"fragmentB");
         }
         init();
     }

     @Override
     protected void onSaveInstanceState(Bundle outState) {
         if( fragmentB != null ){
             getSupportFragmentManager().putFragment(outState,"fragmentB",fragmentB);
         }

         super.onSaveInstanceState(outState);
     }

     /** Fragment中儲存變數的程式碼 **/

     @Nullable
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         AppLog.e("onCreateView");
         if ( null != savedInstanceState ){
             String savedString = savedInstanceState.getString("string");
             //得到儲存下來的string
         }
         View root = inflater.inflate(R.layout.fragment_a,null);
         return root;
     }

 	@Override
     public void onSaveInstanceState(Bundle outState) {
         outState.putString("string","anAngryAnt");
         super.onSaveInstanceState(outState);
     }

靜態的使用Fragment
  • 繼承Fragment,重寫onCreateView決定Fragment的佈局
  • 在Activity中宣告此Fragment,就和普通的View一樣
Fragment常用的API
  • android.support.v4.app.Fragment 主要用於定義Fragment
  • android.support.v4.app.FragmentManager主要用於在Activity中操作Fragment,可以使用FragmentManager.findFragmenById,FragmentManager.findFragmentByTag等方法去找到一個Fragment
  • android.support.v4.app.FragmentTransaction 保證一些列Fragment操作的原子性,熟悉事務這個詞
  • 主要的操作都是FragmentTransaction的方法(一般我們為了向下相容,都使用support.v4包裡面的Fragment)
  • 主要的操作都是FragmentTransaction的方法
  • FragmentTransaction transaction = fm.benginTransatcion();//開啟一個事務
    	transaction.add() 
    	//往Activity中新增一個Fragment
    
    	transaction.remove() 
    	//從Activity中移除一個Fragment,如果被移除的Fragment沒有新增到回退棧(回退棧後面會詳細說),這個Fragment例項將會被銷燬。
    
    	transaction.replace()
    	//使用另一個Fragment替換當前的,實際上就是remove()然後add()的合體~
    
    	transaction.hide()
    	//隱藏當前的Fragment,僅僅是設為不可見,並不會銷燬
    
    	transaction.show()
    	//顯示之前隱藏的Fragment
    
    	detach()
    	//當fragment被加入到回退棧的時候,該方法與*remove()*的作用是相同的,
    	//反之,該方法只是將fragment從檢視中移除,
    	//之後仍然可以通過*attach()*方法重新使用fragment,
    	//而呼叫了*remove()*方法之後,
    	//不僅將Fragment從檢視中移除,fragment還將不再可用。
    
    	attach()
    	//重建view檢視,附加到UI上並顯示。
    
    	transatcion.commit()
    	//提交一個事務


管理Fragment回退棧
  • 跟蹤回退棧狀態,我們通過實現*OnBackStackChangedListener*介面來實現回退棧狀態跟蹤,具體如下
 public class XXX implements FragmentManager.OnBackStackChangedListener 

 /** 實現介面所要實現的方法 **/

 @Override
 public void onBackStackChanged() {
     //do whatevery you want
 }

 /** 設定回退棧監聽介面 **/
 getSupportFragmentManager().addOnBackStackChangedListener(this);
  • 管理回退棧
  1. FragmentTransaction.addToBackStack(String) --將一個剛剛新增的Fragment加入到回退棧中

  2. getSupportFragmentManager().getBackStackEntryCount()--獲取回退棧中實體數量

  3. getSupportFragmentManager().popBackStack(String name, int flags)--根據name立刻彈出棧頂的fragment

  4. getSupportFragmentManager().popBackStack(int id, int flags) --根據id立刻彈出棧頂的fragment

福利

掃描二維碼,下載銀聯旗下APP-雲閃付,註冊綁卡,即可領紅包(8.8~2018元)!

每天都能領!!!

每天都能領!!!

每天都能領!!!