1. 程式人生 > >Fragment重疊,使用show和hide控制顯示和隱藏介面重疊問題;

Fragment重疊,使用show和hide控制顯示和隱藏介面重疊問題;

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