Fragment生命週期

Fragment生命週期

這裏寫圖片描述

詳細解讀每個方法的調用場景

  1. onAttach方法, Fragment和Activity建立關聯的時候調用(獲得activity的傳遞的值)
  2. onCreateView方法, 爲Fragment創建視圖(加載佈局)時調用(給當前的fragment繪製UI佈局,可以使用線程更新UI)
  3. onActivityCreated方法, 當Activity中的onCreate方法執行完後調用(表示activity執行oncreate方法完成了的時候會調用此方法)
  4. onDestroyView方法 ,Fragment中的佈局被移除時調用(表示fragment銷燬相關聯的UI佈局)
  5. onDetach方法, Fragment和Activity解除關聯的時候調用(脫離activity)

fragment生命週期解析

當一個fragment被創建的時候:

onAttach()
onCreate()
onCreateView()
onActivityCreated()

當這個fragment對用戶可見的時候,它會經歷以下狀態。

onStart()
onResume()

可以理解爲從創建到顯示(或切換)

當這個fragment進入“後臺模式”的時候,它會經歷以下狀態。
onPause()
onStop()

當這個fragment被銷燬了(或者持有它的activity被銷燬了):

onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

就像Activity一樣,在以下的狀態中,可以使用Bundle對象保存一個fragment的對象。

onCreate()
onCreateView()
onActivityCreated()

其他場景的調用

屏幕滅掉

onPause()
onSaveInstanceState()
onStop()

屏幕解鎖

onStart()
onResume()

切換到其他Fragment

onPause()
onStop()
onDestroyView()

切換回本身的Fragment

onCreateView()
onActivityCreated()
onStart()
onResume()

回到桌面

onPause()
onSaveInstanceState()
onStop()

回到應用

onStart()
onResume()

退出應用

onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

hide和show方式生命週期

現有Fragment1和Fragment2

載入Fragment1,生命週期如下:

  1. Fragment1 onCreate
  2. Fragment1 onCreateView
  3. Fragment1 onStart
  4. Fragment1 onResume

用add和add切到Fragment2

  FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.hide(Fragment1);
        ft.add(R.id.simple_fragment, Fragment2);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

Fragment1不走任何生命週期,但會調onHiddenChanged方法
1. Fragment2 onCreate
2. Fragment2 onCreateView
3. Fragment2 onStart
4. Fragment2 onResume

用hide和show的方式切換都不會走生命週期

  • 使用hide()方法只是隱藏了fragment的view並沒有將view從viewtree中刪除,隨後可用show()方法將view設置爲顯示。
  • 原本需要在onResume以及onPause方法做的事情就可以遷移到onHiddenChanged時進行管理

回到Fragment1,Remove Fragment2

FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.remove(Fragment2);
        ft.show(Fragment1);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

Fragment1還是不走任何生命週期,調onHiddenChanged方法
Fragment2 onPause
Fragment2 onStop
Fragment2 onDestoryView
Fragment2 onDestory
用這種方法切換,Fragment在隱藏時並不會走onDestoryView,所以顯示時也不會走onCreateView,所有View都一直保存在內存中。

replace方式生命週期

Fragment1用replace切到Fragment2

 FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.simple_fragment, Fragment2);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

這次的Fragment1走生命週期了
Fragment1 onPause
Fragment1 onStop
Fragment1 onDestoryView
Fragment1 onDestory
Fragment2 onCreate
Fragment2 onCreateView
Fragment2 onStart
Fragment2 onResume

Fragment2回到Fragment1

 FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.simple_fragment, Fragment1);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

Fragment1 onCreate
Fragment1 onCreateView
Fragment1 onStart
Fragment1 onResume
Fragment2 onPause
Fragment2 onStop
Fragment2 onDestoryView
Fragment2 onDestory
Fragment1因爲已經被回收,又走onCreate,Fragment2被回收。

這兩種方式顯然都不滿足我的需求,且與生命週期圖不同。因爲我需要在用戶看見/看不見Fragment時register和unregister BroadcastReceiver之類的東西(onHiddenChanged也能實現,但第一次載入顯示,以及銷燬時不會走onHiddenChanged方法),也不希望用戶回到上一個Fragment就重新創建整個Fragment,因爲這樣消耗資源。

ViewPager裏生命週期

根據setUserVisibleHint(boolean isVisibleToUser) 來判斷顯示隱藏

總結

使用add()加入fragment時將觸發onAttach(),使用attach()不會觸發onAttach()
使用replace()替換後會將之前的fragment的view從viewtree中刪除
觸發順序:
detach()->onPause()->onStop()->onDestroyView()
attach()->onCreateView()->onActivityCreated()->onStart()->onResume()
使用hide()方法只是隱藏了fragment的view並沒有將view從viewtree中刪除,隨後可用show()方法將view設置爲顯示
而使用detach()會將view從viewtree中刪除,和remove()不同,此時fragment的狀態依然保持着,在使用attach()時會再次調用onCreateView()來重繪視圖,注意使用detach()後fragment.isAdded()方法將返回false,在使用attach()還原fragment後isAdded()會依然返回false(需要再次確認)
執行detach()和replace()後要還原視圖的話, 可以在相應的fragment中保持相應的view,並在onCreateView()方法中通過view的parent的removeView()方法將view和parent的關聯刪除後返回

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