FragmentPagerAdapter vs FragmentStatePagerAdapter

參考:

http://cammykamal.blogspot.hk/2015/05/fragmentstatepageradapter-vs.html

看了一大段英文,勉強懂得一些,但還是看源碼來的快;

最大的區別就是:

  1. FragmentPagerAdapter:不會摧毀Fragment實例,只會摧毀Fragment 的View;
    特別注意:實例與Fragment的View是有區別的;沒有真正摧毀,只是調用了 detach 方法,此時Fragment的成員變量,如:List<Bitmap>,會一直存在并占用著內存,如果多個Fragment都含有占用內存的成員變量,最好不要使用FragmentPagerAdaper,則使用下面的StatePagerAdappter;
  2. FragmentStatePagerAdapter:直接摧毀Fragment,即調用remove方法,但移除之前,會保存Fragment相關的狀態,我們可以在 onSaveInstance 等相關方法中來進行數據的保存;

具體代碼:

  • 初始化方法(instantiateItem):
  • FragmentPagerAdapter:
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // 省略部分代碼
        final long itemId = getItemId(position);
    
        String name = makeFragmentName(container.getId(), itemId);
        // 這里先查找
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {  // 找到了,直接 attach
            mCurTransaction.attach(fragment);
        } else {  // 否則創建新的fragment,并添加
            fragment = getItem(position);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        
        // 省略部分代碼
        return fragment;
    } 
    
  • FragmentStatePagerAdapter:
 @Override
 public Object instantiateItem(ViewGroup container, int position) {
     // If we already have this item instantiated, there is nothing
     // to do.  This can happen when we are restoring the entire pager
     // from its saved state, where the fragment manager has already
     // taken care of restoring the fragments we previously had instantiated.
     if (mFragments.size() > position) {
         Fragment f = mFragments.get(position);
         if (f != null) {
             return f;
         }
     }

     // 省略部分代碼

     // 獲取fragment,有狀態則還原
     Fragment fragment = getItem(position);
     if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
     if (mSavedState.size() > position) {  
         Fragment.SavedState fss = mSavedState.get(position);
         if (fss != null) {
             fragment.setInitialSavedState(fss);
         }
     }
    
      // 省略代碼
     mCurTransaction.add(container.getId(), fragment);

     return fragment;
 }
  • 銷毀方法(destroyItem)
    • FragmentPagerAdapter:
        public void destroyItem(ViewGroup container, int position, Object object) {
         if (mCurTransaction == null) {
             mCurTransaction = mFragmentManager.beginTransaction();
         }
         if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                 + " v=" + ((Fragment)object).getView());
         mCurTransaction.detach((Fragment)object);  // detach 的,只是銷毀View
      }
      
    • FragmentStatePagerAdapter:
       @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
          Fragment fragment = (Fragment) object;
          if (mCurTransaction == null) {
              mCurTransaction = mFragmentManager.beginTransaction();
          }
          if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
                  + " v=" + ((Fragment)object).getView());
          while (mSavedState.size() <= position) {
              mSavedState.add(null);
          }
          // 移除前,會保存狀態
          mSavedState.set(position, fragment.isAdded()
                  ? mFragmentManager.saveFragmentInstanceState(fragment) : null);
          mFragments.set(position, null);
      
          mCurTransaction.remove(fragment);    // 直接移除了
      }
      
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容