1. 程式人生 > >Android中Fragment巢狀生命週期響應問題

Android中Fragment巢狀生命週期響應問題

問題闡述 :

主介面有四個Fragment 分別為A、B、C、D 這些為第一層Fragment(建立方式是由事務提交形式),其中B Fragment中佈局為ViewPager,裡面是放的三個Fragment 分別為B_1、B_2、B_3,這些稱為第二層Fragment
那麼在切換第一層Fragment時候,怎樣使第二層Fragment呼叫其生命週期? 並且使得第一層Fragment能夠快取View?

我們首先來看 Fragment週期圖:

由圖可以知道 Fragment生命週期觸發方式是有兩種方式:即通過事務提交方式,還有一種是通過inflate 方式,由此我們知道案例中的第二層Fragment建立方式是inflate方式,所以要想第一層B的Fragment中能呼叫第二層的Fragment生命週期,就需要在B中呼叫
getChildFragmentManager

,而不能使用getFragmentManager(),另一方面雖然此時可以實現B對第二層Fragment生命週期的呼叫,但是並不能實現對第一層Fragment的快取處理即對 mViewRoot的複用,想要複用就需要額外處理,見下面程式碼:
如果一個Fragment內部嵌套了Fragment,內部的Fragment切換的時候要能夠呼叫內部Fragment的生命週期:
1、內部切換要用getChildFragmentManager
2、外部的Fragment切換的時候,onCreateView呼叫的時候不能快取View,需要每次inflater.inflate才會走子Fragment的生命週期

那麼一般情況下切換第一次層的Fragment時候,B中Fragment是不會走生命週期的,那麼如何解決這個問題尼?

1 、在B Fragment中使用getChildFragmentManager

2、在B Fragment中使用如下程式碼

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

       if (!needReUseRootView() || mViewRoot == null
) { mViewRoot = inflater.inflate(R.layout.fragment_base, container, false); } } protected boolean needReUseRootView() { return false; }

相應的在 第一層的其他Fragment中

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

       if (!needReUseRootView() || mViewRoot == null) {
          mViewRoot = inflater.inflate(R.layout.fragment_base, container, false);
       }
    }

    protected boolean needReUseRootView() {
        return true;
    }