Android FragmentManager使用
總結了一篇關於fragment管理的文章,之前一直很迷,現在實踐後終於完全理解啦,歡迎各位大佬閱讀修正
1.獲取fragmentManager
要想使用好fragmentmanager,第一步肯定先要正確獲取他呀:
- 獲取activity中的fragmentmanager:在activity中
getFragmentManager()
或getSupportFragmentManager()
(這個用於support包的fragment,向下相容,現api28後變成support包全部轉為Androidx)如果在fragment中則可以先getactivity()
獲取到其依賴的activity - 獲取在fragment中的fragmentmanager:
getChildFragmentManager()
這種情況用於fragment中巢狀fragment,同時子fragment可以通過getParentFragment()
獲得
2.事務
- 在Android中fragmentManager是以事務為單位來管理的,每次我們都通過
fragmentManager.beginTransaction()
來獲得一個FragmentTransaction物件,然後進行新增,替換,刪除等,最後commit提交,這整個過程從begin到commit進行的所有操作就是一個事務,每個commit提交一個事務 - 這裡要注意commit呼叫commit()方法並不立即執行這個事務,而是在Activity的UI執行緒之上(”main”執行緒)排程執行,以便這個執行緒能夠儘快執行這個事務,這意味這個commit是非同步的,所以必要時可以通過
commitNow()
來立即執行
2.fragmentManager的各種方法
add()
add方法會直接將一個fragment新增到指定的id佈局中,不管這個佈局容器中原來有沒有,無條件覆蓋。所以會疊加,而之前的fragment只是被遮擋,view並不會被摧毀getFragmentbyTag()
與getFragmentbyId()
這兩個方法可以獲得有相應的tag或id屬性的fragment(這兩個屬性也可以通過xml里布局設定),那麼就出現了有多個fragment擁有相同的tag和id,那呼叫該方法獲得的是哪個呢?實測獲得的是最頂層的那個fragment,也就是最近新增的replace()
該方法不同於add()可有其註釋的出,relplace()會先相應呼叫該佈局id容器中中所有的add的fragment的remove()
方法,然後在呼叫add()
方法remove()
移除這個fragment,最後會呼叫onDetach()
show()
和hide()
,這裡要注意呼叫這兩個方法並不會走fragment的生命週期,which means 並不會呼叫onPause()
,onStop
方法,而是隻呼叫了onHiddenChanged()
方法,所有改變應在這個方法裡,重寫之addToBackTrack()
最後說一下fragment的回退棧,注意,只有在commit事務是呼叫了addToBackTrack()
方法,才會有回退棧,才會在回退棧裡新增,否則就沒有回退棧,pop方法不會有任何改變。addToBackTrack()
即把本次事務的所有操作儲存起來,注意呼叫了addtobaktrack後remove方法不會真的把fragment移除,而只是distroy了它的view,並沒有呼叫onDetach()
,也就是說它還連線在宿主中。popbackTrack
,該方法即將回退棧中的最近的一次事務pop出來,也就是反過來呼叫方法,add就是remove,remove就add,所以如果這個呼叫了replace,那麼pop後就會將這個replace add的fragment移除,然後在把之前remove的所有fragment add到裡面。而之前就存在的fragment依然存在,沒有變化,就像是add覆蓋到上面一樣。所以加入回退棧後pop可以回到上次操作