ViewPager中使用Fragment时防止数据预加载,安卓app开发教程

 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;

}




在instantiateItem方法的最后我们发现了调用的地方:



if (fragment != mCurrentPrimaryItem) {

fragment.setMenuVisibility(false);

fragment.setUserVisibleHint(false);

}




这里有个判断`fragment != mCurrentPrimaryItem`这个时候会把Fragment的Visible设为false, 那这个`mCurrentPrimaryItem`又是什么呢,继续搜索源码:



@SuppressWarnings(“ReferenceEquality”)

@Override

public void setPrimaryItem(ViewGroup container, int position, Object object) {

Fragment fragment = (Fragment)object;

if (fragment != mCurrentPrimaryItem) {

    if (mCurrentPrimaryItem != null) {

        mCurrentPrimaryItem.setMenuVisibility(false);

        mCurrentPrimaryItem.setUserVisibleHint(false);

    }

    if (fragment != null) {

        fragment.setMenuVisibility(true);

        fragment.setUserVisibleHint(true);

    }

    mCurrentPrimaryItem = fragment;

}

}




在一个`setPrimaryItem`的方法中找到这个变量的赋值,这个方法将传进来的fragment的visible设置为true, 同时会更新mCurrentPrimaryItem变量的值。我们再继续搜索`setPrimaryItem`这个方法的调用,结果在当前FragmentPagerAdapter的源码中没有找到,但是在它的父类PagerAdapter的源码中找到了它的定义:



/**

 * Called to inform the adapter of which item is currently considered to

 * be the "primary", that is the one show to the user as the current page.

 *

 * @param container The containing View from which the page will be removed.

 * @param position The page position that is now the primary.

 * @param object The same object that was returned by

 * {@link #instantiateItem(View, int)}.

 */

public void setPrimaryItem(ViewGroup container, int position, Object object) {

    setPrimaryItem((View) container, position, object);

} 



看注释大概明白了这个方法的含义是设置为ViewPager中当前展示给用户的那一页。  

继续到ViewPager的源码中搜索,找到了调用它的地方:



![这里写图片描述](https://www.icode9.com/i/?i=20180823102720567?)



是在一个`populate()`的方法中调用的,搜索发现好多地方调用了它,但是发现了有两个关键的地方:



/**

 * Set a PagerAdapter that will supply views for this pager as needed.

 *

 * @param adapter Adapter to use

 */

public void setAdapter(PagerAdapter adapter) {

    //...忽略部分源码



    if (mAdapter != null) {

        //...忽略部分源码

        if (mRestoredCurItem >= 0) {

            mAdapter.restoreState(mRestoredAdapterState, mRestoredClassLoader);

            setCurrentItemInternal(mRestoredCurItem, false, true);

            mRestoredCurItem = -1;

            mRestoredAdapterState = null;

            mRestoredClassLoader = null;

        } else if (!wasFirstLayout) {

            populate();

        } else {

            requestLayout();

        }

    }



    //...忽略部分源码

} 

/**

  * Set the currently selected page.

  *

  * @param item Item index to select

  * @param smoothScroll True to smoothly scroll to the new item, false to transition immediately

  */

 public void setCurrentItem(int item, boolean smoothScroll) {

     mPopulatePending = false;

     setCurrentItemInternal(item, smoothScroll, false);

 }



 void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) {

     setCurrentItemInternal(item, smoothScroll, always, 0);

 }



 void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {

   

     //...忽略部分源码



     if (mFirstLayout) {

         // We don't have any idea how big we are yet and shouldn't have any pages either.

         // Just set things up and let the pending layout handle things.

         mCurItem = item;

         if (dispatchSelected) {

             dispatchOnPageSelected(item);

         }

         requestLayout();

     } else {

         populate(item);

         scrollToItem(item, smoothScroll, velocity, dispatchSelected);

     }

 } 

```


 
上一篇:Android Fragment 使用解析,干货分享


下一篇:Android 开发必备知识点及面试题汇总(Android+Java,Android基础开发与实践