Fragment切換replace,add,remove,hidden

今天在實踐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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章