今天在實踐androidX的fragment懶加載方案的時候,又複習了一下fragment的切換。以前沒有時間記下來,今天就記錄一下吧。
1、使用replace切換fragment
我們都知道我們在同一個FrgmentLayout中切換不同的fragment的時候,我們可以直接用replace,那麼用replace的時候,我們之前加進去的fragment是什麼狀態呢。下面我們實踐一下。
private fun changeFragment(index: Int) {
ft = fm.beginTransaction()
var currentFragmnet:Fragment? = null
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
}
currentFragmnet = oneFragment as OneFragment
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
}
currentFragmnet = twoFragment as TwoFragment
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
}
currentFragmnet = threeFragment as ThreeFragment
}
}
if (currentFragmnet == null){
currentFragmnet = OneFragment()
}
ft.replace(mDataBinding.flFragment.id,currentFragmnet).commit()
}
我在界面上設置了三個按鈕,然後對應創建了三個fragment。先看看當首次進入頁面,加入第一個fragment的時候生命週期是什麼樣子的
這是一個正常顯示fragment的生命週期,然後我在切換到第二個fragment,查看生命週期的改變
可以看到上一個顯示的fragment是被銷燬了的,然後創建顯示了第二個fragment,然後再切換會第一個fragment,查看生命週期變化,
可以很清楚的看到,第二個fragment被銷燬移除,然後新建了第一個fragment。所以我們使用replace的時候,實際上就等同於我們把之前一個fragment移除了,然後add了一個新的fragment。驗證一下我們實踐一下,add和remove:
private fun changeFragmentRemoveAndAdd(index: Int) {
ft = fm.beginTransaction()
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
}
ft.add(mDataBinding.flFragment.id, oneFragment!!)
if (twoFragment != null){
ft.remove(twoFragment!!)
}
if (threeFragment!=null){
ft.remove(threeFragment!!)
}
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
}
ft.add(mDataBinding.flFragment.id, twoFragment!!)
if (oneFragment != null){
ft.remove(oneFragment!!)
}
if (threeFragment!=null){
ft.remove(threeFragment!!)
}
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
}
ft.add(mDataBinding.flFragment.id, threeFragment!!)
if (twoFragment != null){
ft.remove(twoFragment!!)
}
if (oneFragment!=null){
ft.remove(oneFragment!!)
}
}
}
ft.commit()
}
先看加入第一個fragment的時候的生命週期:
這個沒什麼好說的,第一個加入生命週期肯定都是一樣的,直接看切換的時候的生命週期:
可以看到和replace是一樣的,然後再切換會第一個fragment:
切換回來生命週期也是一樣的。如果我們在切換fragment的時候想要不保留之前的顯示的狀態,我們就可以把之前的fragment remove掉然後添加我們想要的新fragment。我覺得還是用replace比add+remove方便多了。但是有的時候我們想要保留之前的fragment狀態,這個時候我們就不能去remove和add了,我們應該要show和hidden。如下:
private fun changeFragmentShowAndHidden(index: Int) {
ft = fm.beginTransaction()
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
ft.add(mDataBinding.flFragment.id, oneFragment!!)
}else {
ft.show(oneFragment!!)
}
if (twoFragment != null){
ft.hide(twoFragment!!)
}
if (threeFragment!=null){
ft.hide(threeFragment!!)
}
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
ft.add(mDataBinding.flFragment.id, twoFragment!!)
}else{
ft.show(twoFragment!!)
}
if (oneFragment != null){
ft.hide(oneFragment!!)
}
if (threeFragment!=null){
ft.hide(threeFragment!!)
}
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
ft.add(mDataBinding.flFragment.id, threeFragment!!)
}else{
ft.show(threeFragment!!)
}
if (twoFragment != null){
ft.hide(twoFragment!!)
}
if (oneFragment!=null){
ft.hide(oneFragment!!)
}
}
}
ft.commit()
}
首次進入的時候是添加一個onefragment,生命週期就是正常的創建
切換到twoFragment:
切換回onefragment:
!!!生命週期沒有返回任何改變。
所以這個時候我們的fragment 除了對用戶可見狀態發生了改變,生命週期是沒有受任何影響的。
綜上所訴,我們可以根據我們自己的需求,去選擇使用什麼樣子的方式切換fragment