一. ViewPager各个适配器

1. ViewPager的简单适配器PageAdapter

参看文章第一二小节
实现PageAdaper必须实现它的4个方法

getCount()
返回页面页面数量

Object instantiateItem(ViewGroup container, int position)
将页面的view加入container中, 并返回对应的的key

boolean isViewFromObject(View view, Object object)
判断页面的view和key是否匹配

void destroyItem(ViewGroup container, int position, Object object)
将第position页的view从container中移除

2.使用FragmentPageAdapter

实现两个方法 (FragmentPageAdapter实现了instantiateItem,isViewFromObject,destroyItem)

public int getCount()
返回页面页面数量

Fragment getItem(int position)
返回第position页的Fragment

注意 如下FragmentPagerAdapter的源码

  1. instantitatItem首先从FragmentManager中获取Fragment
    如果没有,则再从getItem中获取
  public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

2 . destroyItem
从FragmentMananger detach掉Fragment,此时Fragment仍然在FragmentManager中

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

3. FragmentPagerStateAdapter

仍然只需要实现 getCount() 和instantiateItem()方法

FragmentPagerStateAdapter相关源码

  1. instantitatItem 逻辑和FramentPagerAapter类似
    首先从FragmentManager中获取Fragment
    如果没有,则再从getItem中获取
  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;
           }
       }

       if (mCurTransaction == null) {
           mCurTransaction = mFragmentManager.beginTransaction();
       }

       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);
           }
       }
       while (mFragments.size() <= position) {
           mFragments.add(null);
       }
       fragment.setMenuVisibility(false);
       fragment.setUserVisibleHint(false);
       mFragments.set(position, fragment);
       mCurTransaction.add(container.getId(), fragment);

       return fragment;
   }

2 . destroyItem
从FragmentMananger remove掉Fragment,此时Fragment不在FragmentManager中

   @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);
    }
  1. FragmentPagerAdapter与FragmentPagerStateAdapter的区别


    一. ViewPager各个适配器_第1张图片
    image

实例

  1. viewpager.setOffscrennPageLimit(1);
  2. 从第一页滑动第二页,会创建第三页
  3. 从第二页滑到第一页,会调用destroyItem摧毁第三页
  4. 区别在于FragmentPagerAdapter与FragmentPagerStateAdapter的destoryItem方法实现不一样。FragmentPagerAdapter会将Fragment从FragmentManger总detach()
    FragmentPagerStateAdapter会将Fragment从FragmentManger总remove()

你可能感兴趣的:(一. ViewPager各个适配器)