(給安卓開發精選加星标)
轉自: Android開發者家園-sydMobile
Fragment 就是一個 Activity 布局的一部分,可以把 Activity 的一部分布局抽離出來到 Fragment 中,并且 Fragment 也可以執行邏輯。就是把 Activity 複雜的内容抽離成幾個碎片,然後拼湊起來,在 Activity 布局中,隻需要引入各個不同的 Fragment 就可以 了。
比如我們常見的布局,底部導航,然後每個子產品對應不同的 Fragment。其實也是完全可以不使用 Fragment 的,一個頁面中包含各個子產品的布局,然後通過點選導航來決定隐藏哪些子產品。這樣寫的話一個 Activity 中的代碼邏輯會非常多,所有子產品都融合到一個 Activity 中了,相當備援,耦合。如果用 Fragment 就靈活多了,Activity 隻需要根據導航顯示對應的 Fragment 就可以了。
如果别的地方需要某一個子產品,直接拿出對應的 Fragment 就可以了。如果都寫在 Activity 中那抽離出來就費勁了,也增加了不确定性。
再比如一個例子:網易新聞 手機端 和平闆端。
平闆端是新聞的标題和詳情都在一個頁面中。手機是詳情在單獨的一個頁面。這樣我們就可以将 标題 和 詳情寫成兩個 Fragment。充分利用了。
Fragment 相關的三個類
-
具體的 FragmentFragment
-
是管理 Fragment 的FragmentManager
-
通過事務來進行添加 Fragment、隐藏、移除 等操作 Fragment 動作,事務保證了原子性FragmentTransaction
主要方法
-
向 Activity 中添加 Fragment,隻是添加 Fragment,不影響之前 Fragment 的聲明周期,這一點和 Activity 不一樣,Activity 會因為新 Activity 而走生命周期。而transaction.add()
不會。假如 FragmentA 已經在 Activity 中了,這個時候啟動了 FragmentB,A 的生命周期是不會有任何變化的,還是處于.add
,并不會因為onResume
處于B
而有影響。onResume
-
從 Activity 中移除一個transaction.remove()
。如果這個 Fragment 沒有被添加到回退棧中,則執行個體被銷毀。如果添加到回退棧了,會執行Fragment
執行個體并不會被銷毀。onDestroyView
-
使用 Fragment 替換目前,相當于先移除之前的 Fragment(remove()) 然後再 add()transaction.replace()
-
隐藏目前 Fragment。僅僅是設為不可見。不會銷毀transaction.hide()
-
顯示之前隐藏的 Fragmenttransaction.show()
-
會将 view 從 UI 中移除。和 remove 不同的是,此時 Fragment的狀态依然由 FragmentManager 維護detach()
-
重建 view 視圖,附加到UI上顯示attach()
-
.addToBackStack()
是将事務放入回退棧,可以認為一個事務中可以有多個 Fragment
.addToBackStack()
做的是将這個事務放入回退棧。
類似于我們每添加一個 Activity 都會預設放入回退棧中,如果想要 Fragment 放入回退棧中,那麼就需要借助啟動 Fragment 的事務了,調用事務的
.addToBackStack()
方法。
預設情況下,按下傳回鍵的時候的操作是從回退棧中彈出一個事務。
按下傳回鍵的時候,是從傳回棧中彈出一個事務(Fragment)。顯示棧頂的事務(對應的 Fragment)
如果目前棧頂的Fragment 已經執行過
了,則會重新執行生命周期(從destroyView
createView
開始)
如果任務棧中隻有一個Fragment,則此時按下傳回鍵,進行的操作是把這個 Fragment 銷毀。
在 Fragment A 中啟動另一個 Fragment B 這個時候
是将 A 加入棧中。.addToBackStack()
基本使用
靜态添加
在代碼中擷取的這個 Fragment
通過
注意靜态添加
Fragment
的生命周期
動态添加
動态添加,一般都會選擇加載到
FrameLayout
布局上,是因為
FrameLayout
布局足夠簡單,可以減少不必要的布局加載。
Fragment 的布局隻是附着在
FrameLayout
上,作為
FrameLayout
的 子 View ,并沒有取代
FrameLayout
Fragment 無論是否是全屏還是一半的,執行生命周期都一樣
執行結果:
傳回
onHiddenChanged()
和普通的生命周期沒有關系,隻是調用
hidden
的時候會調用而已。
通過上面
.add
的方式添加
Fragment
隻是将 Fragment 添加到指定的布局中,之後再添加 Fragment 是互相不影響的,在布局上看
FrameLayout
有兩個子View(FragmentOne、FragmentTwo) 互相重疊。
關于.addToBackStack() 例子
例子1
主 Activity 中一次啟動兩個 Fragment ,并将這個事務加入到回退棧中。
這個時候按下傳回鍵的結果是,從回退棧中彈出這個事務,意味這銷毀這兩個 Fragment
執行結果
Fragment 從 Activity 中脫離,留下 Activity
假如沒有
addToBackStack()
的時候,按下傳回鍵,則直接退出 Activity 了。
例子2
在上面的基礎上,在啟動的 FragmentTwo 中添加方法
這個時候隻是在
fl
中又添加了一個
FragmentThree
,并且這個事務沒有加入到回退棧中,這個時候按下傳回鍵,結果是:
頁面沒有發生任何改變,但是上一次儲存在回退棧的事務被彈出了
這個時候再按下傳回鍵
Activity 就會被銷毀。
例子3
在例子1的基礎上,在添加 FragmentTwo 中添加方法
這個時候再按下傳回鍵,是将這個棧頂的事務退出,這個時候例子1 中的事務就處于棧頂了。頁面顯示的就是例子1中的頁面了。
再次按下傳回鍵,是把例子1中的事務彈出,這個時候留下的就隻有 Activity 了,再次按下傳回鍵,彈出 Activity。
與 Activity 通信
- Activity 中有 Fragment 的引用,可以直接操作 Fragment 中的方法
- 每個 Fragment 都有一個唯一的 TAG或者 ID 可以通過
擷取getFragmentManager.findFragmentByTag() 或者 findFragmentById()
- Fragment 中通過
擷取目前綁定的 Activity 執行個體getActivity
Fragment 不應該直接操作其他的 Fragment。應該由管理者 Activity 來進行。
采用接口回調的形式
總結
凡是加入了回退棧
.addToBackStack(null)
之前加入的 Fragment 都不會被銷毀。
比如:
Activity A 中
FragmentTwo 中
請注意 Activity A 中是沒有 addToBackStack 的 ,即使這樣在
FragmentTweo
中
replace
後
FragmentOne
和
FragmentTwo
也不會被銷毀,而是走
onDestroyView()
方法。按下傳回鍵後,恢複
FragmentOne
和
FragmentTwo
從
onCreateView
開始
如果沒有
.addToBackStack(null)
的話,那麼
FragmentOne
和
FragmentTwo
就會被銷毀了。并且按下傳回鍵的時候,就銷毀掉 Activity 了。
頁面1 addTo
頁面2 沒有
E/FragmentThree: onAttach()
E/FragmentThree: onCreate()
E/FragmentTwo: onPause
E/FragmentTwo: onStop
E/FragmentTwo: onDestroyView
E/FragmentOne: onPause
E/FragmentOne: onStop
E/FragmentOne: onDestroyView
E/FragmentThree: onCreateView
E/FragmentThree: onActivityCreated
E/FragmentThree: onStart
E/FragmentThree: onResume
E/FragmentTwo: onDestroy
E/FragmentTwo: onDetach()
E/FragmentOne: onDestroy
E/FragmentOne: onDetach()
- EOF -
推薦閱讀 點選标題可跳轉
1、Android 低功耗藍牙總結
2、打破定式,突破屏障,走出自己的創意舒适區
3、大事情!中國限制 AI 算法出口。網友:這是要阻止XX“下跪”
看完本文有收獲?請分享給更多人
關注「安卓開發精選」,提升安卓開發技術
好文章,我在看❤️