一。屬性
1.setPageMargin
2.setOffscreenPageLimit
二。
1.什么時候調(diào)用PagerAdapter.instantiateItem
//在populate中,遍歷mCurItem之前的, addNewItem滿足這個條件的pos == ii.position && !ii.scrolling
遍歷mCurItem之后的, addNewItem滿足這個條件的pos == ii.position && !ii.scrolling
ItemInfo addNewItem(int position, int index) { ItemInfo ii = new ItemInfo(); ii.position = position; ii.object = mAdapter.instantiateItem(this, position); ii.widthFactor = mAdapter.getPageWidth(position); if (index < 0 || index >= mItems.size()) { mItems.add(ii); } else { mItems.add(index, ii); } return ii; }
void populate(int newCurrentItem) { ... ... // Locate the currently focused item or add it if needed. ItemInfo curItem = null; for (curIndex = 0; curIndex < mItems.size(); curIndex++) { final ItemInfo ii = mItems.get(curIndex); if (ii.position >= mCurItem) { if (ii.position == mCurItem) curItem = ii; break; } } if (curItem == null && N > 0) { curItem = addNewItem(mCurItem, curIndex); } ... ... // Fill 3x the available width or up to the number of offscreen // pages requested to either side, whichever is larger. // If we have no current item we have no work to do. if (curItem != null) { float extraWidthLeft = 0.f; int itemIndex = curIndex - 1; ItemInfo ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; final int clientWidth = getClientWidth(); final float leftWidthNeeded = clientWidth <= 0 ? 0 : 2.f - curItem.widthFactor + (float) getPaddingLeft() / (float) clientWidth; for (int pos = mCurItem - 1; pos >= 0; pos--) { if (extraWidthLeft >= leftWidthNeeded && pos < startPos) { if (ii == null) { break; } if (pos == ii.position && !ii.scrolling) { mItems.remove(itemIndex); mAdapter.destroyItem(this, pos, ii.object); if (DEBUG) { Log.i(TAG, "populate() - destroyItem() with pos: " + pos + " view: " + ((View) ii.object)); } itemIndex--; curIndex--; ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; } } else if (ii != null && pos == ii.position) { extraWidthLeft += ii.widthFactor; itemIndex--; ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; } else { ii = addNewItem(pos, itemIndex + 1); extraWidthLeft += ii.widthFactor; curIndex++; ii = itemIndex >= 0 ? mItems.get(itemIndex) : null; } } ... ... if (extraWidthRight < 2.f) { ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; final float rightWidthNeeded = clientWidth <= 0 ? 0 : (float) getPaddingRight() / (float) clientWidth + 2.f; for (int pos = mCurItem + 1; pos < N; pos++) { if (extraWidthRight >= rightWidthNeeded && pos > endPos) { if (ii == null) { break; } if (pos == ii.position && !ii.scrolling) { mItems.remove(itemIndex); mAdapter.destroyItem(this, pos, ii.object); if (DEBUG) { Log.i(TAG, "populate() - destroyItem() with pos: " + pos + " view: " + ((View) ii.object)); } ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; } } else if (ii != null && pos == ii.position) { extraWidthRight += ii.widthFactor; itemIndex++; ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; } else { ii = addNewItem(pos, itemIndex); itemIndex++; extraWidthRight += ii.widthFactor; ii = itemIndex < mItems.size() ? mItems.get(itemIndex) : null; } } } }
2.什么時候調(diào)用PagerAdapter.destroyItem
//在dataSetChanged中遍歷mItems,利用PagerAdapter.getItemPosition() destroyItem pos
//在populate中,遍歷mCurItem之前的, destroyItem滿足這個條件的pos == ii.position && !ii.scrolling
遍歷mCurItem之后的, destroyItem滿足這個條件的pos == ii.position && !ii.scrolling
void dataSetChanged() { ... ... for (int i = 0; i < mItems.size(); i++) { final ItemInfo ii = mItems.get(i); final int newPos = mAdapter.getItemPosition(ii.object); if (newPos == PagerAdapter.POSITION_UNCHANGED) { continue; } if (newPos == PagerAdapter.POSITION_NONE) { mItems.remove(i); i--; if (!isUpdating) { mAdapter.startUpdate(this); isUpdating = true; } mAdapter.destroyItem(this, ii.position, ii.object); needPopulate = true; if (mCurItem == ii.position) { // Keep the current item in the valid range newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1)); needPopulate = true; } continue; } ... ... }
原理:
3.什么時候調(diào)用populate(item)
item是curItem
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); } }
在onRestoreInstanceState,
onTouchEvent(MotionEvent ev) MotionEvent.ACTION_UP mIsBeingDragged==true時,
程序員調(diào)用setCurrentItem,setAdapter, endFakeDrag時
dataSetChanged,
private class PagerObserver extends DataSetObserver { PagerObserver() { } @Override public void onChanged() { dataSetChanged(); } @Override public void onInvalidated() { dataSetChanged(); } }
PagerAdapter.java:
public void notifyDataSetChanged() { synchronized (this) { if (mViewPagerObserver != null) { mViewPagerObserver.onChanged(); } } mObservable.notifyChanged(); }
也就說除非用戶自己調(diào)用setCurrentItem,setAdapter, endFakeDrag,PagerAdapter.notifyDataSetChanged ,只有在ACTION_UP時,才會調(diào)用populate(item)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70766.html
摘要:最后,當(dāng)一次更新添加和或移除完成之后將會調(diào)用來通知提交關(guān)聯(lián)和或取消關(guān)聯(lián)的操作。懶加載的實現(xiàn)弊端概念當(dāng)需要時才加載,加載之后一直保持該對象。而且為了實現(xiàn)滑動效果,都是預(yù)加載左右兩側(cè)的頁面。預(yù)加載的預(yù)加載機制。 目錄介紹 01.ViewPager簡單介紹 02.ViewPager弊端分析 03.ViewPager預(yù)加載 04.ViewPager部分源碼 05.懶加載出現(xiàn)問題 06.如何實...
摘要:前言最近我在關(guān)注的使用,期間一直基于官方的調(diào)試,今天遇到一個奇葩的問題,捉摸了半天最終找到原因,原來是中布局的問題,事后感覺有必要分享一下這個過程,一來可以鞏固測量的知識,二來希望大家能避開這個坑閱讀指南代碼基于,看官老爺最好能下載前言 最近我在關(guān)注ViewPager2的使用,期間一直基于官方的Demo調(diào)試android-viewpager2,今天遇到一個奇葩的問題,捉摸了半天最終找到原因,...
閱讀 3494·2021-11-24 11:17
閱讀 2281·2021-11-15 11:38
閱讀 3367·2021-10-14 09:42
閱讀 2930·2019-08-30 15:54
閱讀 2024·2019-08-28 18:09
閱讀 538·2019-08-26 11:48
閱讀 1632·2019-08-26 10:48
閱讀 2146·2019-08-26 10:45