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