美文网首页
FragmentPagerAdapter vs Fragment

FragmentPagerAdapter vs Fragment

作者: zhaoyubetter | 来源:发表于2017-07-04 15:45 被阅读279次

    参考:

    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);    // 直接移除了
        }
        

    相关文章

      网友评论

          本文标题:FragmentPagerAdapter vs Fragment

          本文链接:https://www.haomeiwen.com/subject/dvhxhxtx.html