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());