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.www.zyiz.net/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); } } ```