Fragment重疊,使用show和hide控制顯示和隱藏介面重疊問題;
阿新 • • 發佈:2019-02-19
Fragment重疊原因:
App因某種原因崩潰自動重啟,或App長期在後臺執行Fragment依賴的activity被回收等等原因;當系統記憶體不足,Fragment 的依附Activity 被回收的時,Fragment 的例項並沒有隨之被回收。Activity被系統回收時,會主動呼叫 onSaveInstance() 方法來儲存檢視層,當Activity通過再次被重建時,之前被例項化過的 Fragment 會出現在Activity中,此時的 FragmentTransaction 中的相當於又再次 add 了 fragment 進去的,hide()和show()方法對之前儲存的fragment已經失效了,所以就出現了重疊;
復現BUG:
設定 -- 開發者選項 -- 不保留活動(開啟);這樣設定後按HOME鍵Activity就會被回收。方式一:(不推薦使用)
Activity被系統回收時,會主動呼叫 onSaveInstance() 方法來儲存檢視層;簡單粗暴:不讓它儲存;
@Override protected void onSaveInstanceState(Bundle outState) { //不儲存之前的fragment的狀態 // super.onSaveInstanceState(outState); }
方式二:(推薦使用)
重寫onAttachFragment,重新讓新的Fragment指向了原本未被銷燬的fragment;
@Override public void onAttachFragment(Fragment fragment) { //重新讓新的Fragment指向了原本未被銷燬的fragment,它就是onAttach方法對應的Fragment物件 if (HomeFm == null && fragment instanceof Fragment1) HomeFm = fragment; if (SpcFm == null && fragment instanceof Fragment2) SpcFm = fragment;if (OrderFm == null && fragment instanceof Fragment3) OrderFm = fragment; if (MyFm == null && fragment instanceof Fragment4) MyFm = fragment; super.onAttachFragment(fragment); }
方式三:(推薦使用)
在FragmentActivity儲存所有Fragment狀態前把Fragment從FragmentManager中移除掉;
*/ protected void onSaveInstanceState(Bundle outState) { //在FragmentActivity儲存所有Fragment狀態前把Fragment從FragmentManager中移除掉。 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.remove(HomeFm); transaction.remove(SpcFm); transaction.remove(OrderFm); transaction.remove(MyFm); transaction.commitAllowingStateLoss(); super.onSaveInstanceState(outState); }
方式四:
Fragment儲存自己是否顯示;
public class BaseFragment extends Fragment { /** * FragmentState沒幫我們儲存Hidden狀態,那就我們自己來儲存,在頁面重啟後,我們自己來決定Fragment是否顯示! */ private static final String STATE_SAVE_IS_HIDDEN = "CCB_IS_HIDDEN"; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN); FragmentTransaction ft = getFragmentManager().beginTransaction(); if (isSupportHidden) { ft.hide(this); } else { ft.show(this); } ft.commit(); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden()); } }