[ Android ] Fragment 使用筆記

內文為使用 Fragment 的使用心得與筆記





1. android.app.Fragment 與 android.support.v4.app.Fragment


Fragment有不同的Library做處理

v4版本的出現是為了要支援Android 3.0以前的版本

也就是說支援的系統版本只要是3.0以上就建議直接使用原生的 app.Fragment

然而原生的app.Fragment有使用上的一些限制

例如 FragmentManager 中 getFragments() 限定為 Android 8.0 以上才支援

最近因為專案上的需求又跑回去看了一次Fragment的東西

發現官網上app.Fragment的頁面上標示了一條訊息 ( 如下圖 )


來源:https://developer.android.com/reference/android/app/Fragment


在API 28之後 app.Fragment 就不建議被使用了

建議使用 Support Library 獲得更良好的跨裝置支援性

所以之前開檔案手賤全換成 app.Fragment 這下要全換回來

不過也好,原本使用 app.Fragment 時發生的一些怪問題似乎都解決了



2. android.support.v4.app.Fragment 使用上的注意事項


v4版本的Fragment 使用時需要透過 getSupportFragmentManager() 取得管理器

而不是getFragmentManager()



3. 關於 add、hide、show、remove與replace


Fragment 提供幾個控制的方法,如同小標題所示

replace使用上最簡單直覺,意思就是替換掉目前畫面的Fragment

例如,將FragmentA移除 -> 加入FragmentB -> 顯示FragmentB

整個過程動用到 add、remove與show

會跑過Fragment完整的生命流程


而使用add、remove與show流程上就比較繁瑣,相對來說會有最大的彈性

重點在於要自行控制各Fragment顯示與隱藏

例如目前是顯示FragmentA,想要替換成FragmentB

結果沒有將FragmentA收起來( hide )就直接顯示FragmentB

這樣會導致兩個Fragment交疊在一起 ( 同時顯示兩個畫面 )

重點在於FragmentA只是收起來不顯示而已

並不會觸發Fragment的完整生命流程,除非被系統強制回收之類的


至於要使用哪一個方法來就看自己的情況

如果Fragment有高頻率重複使用的特性,建議是用 show 與 hide

反之僅一兩次的話可以使用 replace



4. 關於 popBackStack


popBackStack(String name, int flags)

name 可以為字串或者null

flags則有 0 與 FragmentManager.POP_BACK_STACK_INCLUSIVE 兩種參數

基本上會有以下的狀況

=== name 為null的情況下 ===

flags為0
pop出BackStack最上層的Fragment

flags為 FragmentManager.POP_BACK_STACK_INCLUSIVE
pop出BackStack中所有的Fragment


=== name 不為null的情況下  ===

會以該Tag相對應的Fragment為基準

flags為 0
pop出該Tag以上的Fragment

flags為 FragmentManager.POP_BACK_STACK_INCLUSIVE
pop出包含該Tag以上的Fragment



5. 關於Fragment重疊 ( Overlapping ) 的解決辦法

Fragment有一個地方要注意,由於Fragment需要依賴Activity來顯示

因此Fragment的生命週期與Activity緊緊相扣

當Fragment退回背景或者Activity被系統回收之類的事情發生

例如畫面翻轉時,Activity會重新跑一次生命週期

因而嚴重影響到Fragment的運作

相關的預防方法如下


a. 重新指定Fragment物件

Activity重啟之後,Fragment畫面雖然會保留,但原先的變數資料會消失

因此需要透過下列的方法來重新指定Fragment




b. 保存特定的Fragment

在實驗專案中,使用一個currentFragment來記錄當下畫面所顯示的Fragment

而Activity重啟之後currentFragment會變成null的情況

但這個狀況可以透過下列的程式碼來處理


onSaveInstanceState(Bundle outState)方法中

透過FragmentManager的putFragment()方法來儲存指定的Fragment

( 如同處理Bundle一樣 )


而在onCreate(Bundle saveInstanceState)方法中

先判斷 saveInstanceState 物件是否為 null

如果不為空則透過FragmentManager物件的getFragment()方法取出先前儲存的Fragment

然後這段可以再寫嚴謹一點,取出Fragment時還可以再次檢查是否為 null


c. 設定Layout的背景顏色

最懶惰的辦法



6. 如何得知目前畫面的Fragment是哪一個,可套用於onBackPressed處理

FragmentManage物件可以設定監聽OnBackStackChangedListener()

當BackStack有變化時便會觸發

透過這樣的特性來檢查目前的Fragment是哪一個



先使用 getBackStackEntryCount() -1 來取得最上層Fragment的Index

再使用Index透過getBackStackEntryAt()方法來取得Fragment便於取的其Tag字串

最後使用Tag字串找出最上層的Fragment,將其設定為 currentFragment





上圖所示的程式碼

popFragment()當中,除了執行popBackStack()之外

也會回傳popBackStack後的 BackStack Size

在 onBackPressed() 中 if 的判斷意思

當 BackStack 剩下一個時,便呼叫父類別的 onBackpressed() 方法

跳出當前的 Activity

































沒有留言:

張貼留言

Layout疑難雜症筆記

 這裡記錄一些Layout時View元件比較特殊的狀況與處理方式,內容會陸續增加。