您的位置:首页
ViewPager部分源码分析一:加载数据
2016-07-17 11:40
288 查看
onMeasure()调用populate(),完成首次数据初始化。
populate()维护ViewPager的page,包括mItems和mAdapter。
populate():
似乎在首次数据初始化时会用到。
第一个for循环实现当前page左边的page处理;当向左滑时,销毁左边的page;当向右滑时,增加左边的page。
第二个for循环实现当前page右边的page处理;当向左滑时,增加右边的page;当向右滑时,销毁右边的page。
即在ViewPager中始终保留的是3个page:左边,当前,右边。(没有override PagerAdapter.getPageWidth()方法的情形下!跟ViewPager的padding也有关系)
其中的两次增加page的情况:
onTouchEvent() --> ViewCompat.postInvalidateOnAnimation() --> BaseViewCompatImpl.postInvalidateOnAnimation() --> View.invalidate()
--> ..这一步也不知道是什么.. --> View.updateDisplayListIfDirty --> View.computeScroll() --> ViewPager.completeScroll() --> ViewCompat.postOnAnimation()
--> BaseViewCompatImpl.postOnAnimation() --> View.postDelayed() --> Handler.getPostMessage() --> 后面就是Handler对消息的处理了。
原来Messge里有一个callback,是Runnable类型的,Handler.handleCallback()在处理消息时就是:
直接调用callback的run()方法。
这么一大串的事情,其实两次增加page的情况就是:ViewPager的mEndScrollRunnable最终在Handler.handleCallback()完成的。
看到run()方法中的populate()方法了么!!
populate()维护ViewPager的page,包括mItems和mAdapter。
populate():
if (curItem == null && N > 0) { curItem = addNewItem(mCurItem, curIndex); }
似乎在首次数据初始化时会用到。
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; } } float extraWidthRight = curItem.widthFactor; itemIndex = curIndex + 1; 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; } } } calculatePageOffsets(curItem, curIndex, oldCurInfo); }
第一个for循环实现当前page左边的page处理;当向左滑时,销毁左边的page;当向右滑时,增加左边的page。
第二个for循环实现当前page右边的page处理;当向左滑时,增加右边的page;当向右滑时,销毁右边的page。
即在ViewPager中始终保留的是3个page:左边,当前,右边。(没有override PagerAdapter.getPageWidth()方法的情形下!跟ViewPager的padding也有关系)
其中的两次增加page的情况:
onTouchEvent() --> ViewCompat.postInvalidateOnAnimation() --> BaseViewCompatImpl.postInvalidateOnAnimation() --> View.invalidate()
--> ..这一步也不知道是什么.. --> View.updateDisplayListIfDirty --> View.computeScroll() --> ViewPager.completeScroll() --> ViewCompat.postOnAnimation()
--> BaseViewCompatImpl.postOnAnimation() --> View.postDelayed() --> Handler.getPostMessage() --> 后面就是Handler对消息的处理了。
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
原来Messge里有一个callback,是Runnable类型的,Handler.handleCallback()在处理消息时就是:
private static void handleCallback(Message message) { message.callback.run(); }
直接调用callback的run()方法。
这么一大串的事情,其实两次增加page的情况就是:ViewPager的mEndScrollRunnable最终在Handler.handleCallback()完成的。
private final Runnable mEndScrollRunnable = new Runnable() { public void run() { setScrollState(SCROLL_STATE_IDLE); populate(); } };
看到run()方法中的populate()方法了么!!
相关文章推荐
- CListCtrl的主要事件及鼠标响应函数
- 第一篇博客的自我介绍
- NKOI 夏令营训练赛1 到不了[B]
- JAVA之NIO按行读写大文件,完美解决中文乱码问题
- TCP通信(一)——同步连接
- Java 多态的详解
- 创业14
- AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识
- 数据库——事务基础
- org.msgpack.core.MessagePacker
- 用户(user)和用户组(group)管理
- 个人Linux发行版SwairOS
- Python 小甲鱼教程 课后练习30 番外篇_需要谨记!!!
- 你未必知道的CSS故事:揭开leading的面纱
- C++转换构造函数与类型转换构造函数
- LinkedHashMap类源码解析
- MySQL online ddl
- [Android]使用RecyclerView替代ListView(一)
- TCP中select函数的理解
- PLSQL Developer实现数据库间表结构和数据对比和同步