使用ViewPager切换Fragment时,防止频繁调用OnCreatView
使用ViewPager切换Fragment,我原先使用系统自带的适配器FragmentPagerAdapter。
切换fragment时,频繁调用oncreatview()。
查看FragmentPagerAdapter的源码,发现两个关键的地方
@Override 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); //该处使用attach导致频繁调用oncreatview 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; } @Override 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()); //该处使用detach导致频繁调用oncreatview mCurTransaction.detach((Fragment)object); }
attach和detach的频繁使用导致了fragment频繁调用oncreatview。
找到元凶了,接下来就好办了。
自定义一个适配器,将attach改为show,将detach改为hide。
完美解决问题。
@Override 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); //用show而不用attach,防止频繁调用oncreatview mCurTransaction.show(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; } @Override 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()); //用hide而不用detach,防止频繁调用oncreatview mCurTransaction.hide((Fragment) object); }