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());
方法三有些繁琐,但是确实很好用。在日常使用时,更推荐使用方法三。

猜你喜欢

转载自blog.csdn.net/u014619545/article/details/91875254