Fragment重疊

Fragment雖然不是Android的四大組件之一,但是其在android中的地位仍然是不可小覷的。可以說,拿來任意一個Android原生的app,你都能發現它的身影。Fragment無處不在!
Fragment在使用時,偶爾會出現重疊的問題。比如橫豎屏切換時……出現這種問題的原因是:當我們旋轉屏幕的時候,activity會被銷燬並重新創建,並且在銷燬之前執行了onSaveInstanceState(Bundle outState)這個方法。這個方法會保存activity的一些信息,其中就包括添加過的fragment,當activity被重新創建時,會初始化其中的變量,這個時候點擊底部導航的話會重新去添加fragment,也就導致了重疊的問題。

解決方法1:

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        L.i("MainActivity onSaveInstanceState");
        //super.onSaveInstanceState(outState);
    }

此方法中註釋掉了super.onSaveInstanceState(outState)。也就是說,在fragment被銷燬了後,不會調用父類的保存狀態的方法。但是缺點也很明顯,fragment的狀態和數據全部丟失,每次都會重新創建和新打開的一樣,不是很好的選擇。

解決方法2:

針對於橫豎屏切換出現重疊,我們可以在fragment依賴的activity中添加如下代碼:

android:configChanges=“keyboardHidden|orientation|screenSize”

當我們切換屏幕時,也就不會在走activity的生命週期方法了,也就不會造成fragment重疊的問題了。
同樣的此方法也有侷限性,僅限於屏幕切換造成的Fragment銷燬重建。而Fragment的銷燬重建也可能是因爲內存不足,從而被gc。

解決方法3(吐血推薦):

在Fragment依賴的activity的onSaveInstanceState(Bundle outState)方法中對fragment進行保存,當activity被恢復時,取出這些fragment即可。
相關示例代碼如下:
//保存Fragment及其狀態
	@Override
    protected void onSaveInstanceState(Bundle outState) {
        if (homeFragment.isAdded())
            getSupportFragmentManager().putFragment(outState, HOME_FRAGMENT_KEY, homeFragment);
        if (assortmentFragment.isAdded())
            getSupportFragmentManager().putFragment(outState, ASSORTMENT_FRAGMENT_KEY, assortmentFragment);
        if (discoveryFragment.isAdded())
            getSupportFragmentManager().putFragment(outState, DISCOVERY_FRAGMENT_KEY, discoveryFragment);
        if (shoppingCartFragment.isAdded())
            getSupportFragmentManager().putFragment(outState, SHOPPING_FRAGMENT_KEY, shoppingCartFragment);
        if (mineFragment.isAdded())
            getSupportFragmentManager().putFragment(outState, MINE_FRAGMENT_KEY, mineFragment);
        super.onSaveInstanceState(outState);
    }
//在oncreate中取出保存的fragment
  if (savedInstanceState != null) {
            homeFragment = (HomeFragment) getSupportFragmentManager().getFragment(savedInstanceState, HOME_FRAGMENT_KEY);
            assortmentFragment = (AssortmentFragment) getSupportFragmentManager().getFragment(savedInstanceState, ASSORTMENT_FRAGMENT_KEY);
            discoveryFragment = (DiscoveryFragment) getSupportFragmentManager().getFragment(savedInstanceState, DISCOVERY_FRAGMENT_KEY);
            shoppingCartFragment = (ShoppingCartFragment) getSupportFragmentManager().getFragment(savedInstanceState, SHOPPING_FRAGMENT_KEY);
            mineFragment = (MineFragment) getSupportFragmentManager().getFragment(savedInstanceState, MINE_FRAGMENT_KEY);
        }
        if (homeFragment == null)
            homeFragment = new HomeFragment();
        if (assortmentFragment == null)
            assortmentFragment = new AssortmentFragment();
        if (discoveryFragment == null)
            discoveryFragment = new DiscoveryFragment();
        if (shoppingCartFragment == null)
            shoppingCartFragment = new ShoppingCartFragment();
        if (mineFragment == null)
            mineFragment = new MineFragment();
        //創建fragment的對象,放入到fragment的Map中
        fragmentStatusMap.put(homeFragment, false);
        fragmentStatusMap.put(assortmentFragment, false);
        fragmentStatusMap.put(discoveryFragment, false);
        fragmentStatusMap.put(shoppingCartFragment, false);
        fragmentStatusMap.put(mineFragment, false);
        fragments = new LinkedList<>();
        fragments.addAll(fragmentStatusMap.keySet());
方法三有些繁瑣,但是確實很好用。在日常使用時,更推薦使用方法三。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章