前言:
对于开博第一篇,花点时间写个前言,哈哈~
先记录下我的初心:
1,作为一个android从业者,发现有价值的开源分享,会有莫名的欣喜,我也跟随大神们的脚步,希望给世界输出点 点滴~
2,android开发需要积累,经验积累,文档代码积累,whatever,给自己留下些可以翻阅的笔记。
3,时代很快,做个会时刻总结的人,去审视昨天的自己,做最好的当下。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
哈哈!
正文开始:
由于要实现ViewPager的无限循环引发的博文案!!
网上不改源代码有两种实现方式:具体请移步该处:http://blog.csdn.net/just_sanpark/article/details/17436037
问题来了,觉得这样在外面实现不过瘾,想在源码内部实现,但是能力还不够独立通读源码进行修改,怎么办?
网络的力量的伟大的~
先上理解ViewPager的实现的前菜(ViewPager基本实现原理),引用郭神博文的一句话:
ViewPager最基本的实现原理主要就是两部分内容,一个是事件分发,一个是Scroller!
垫完肚子之后,上正菜:
我们跟下面的大神通读一遍ViewPager的源码:
博文地址:ViewPager源码解惑
---------------------我是一条美丽的分割线-------------------------------------------------------------------
读源码对于初学者是头疼的过程,一盘大菜,小编还在努力中,也吃不完那么多,所以先从小地方啃起~
回到本文标题:
ctrl进setCurrentItem(int item)方法,见如下:
/**
* Set the currently selected page. If the ViewPager has already been through its first
* layout with its current adapter there will be a smooth animated transition between
* the current item and the specified item.
* @param item Item index to select
*/
public void setCurrentItem(int item) {
mPopulatePending = false;
setCurrentItemInternal(item, !mFirstLayout, false);
}
/**
* 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);
}
mPopulatePending 是否正在填充的控制变量,方法重载是设置是否需要平滑的切换动画。
两方法都进入到setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity)中
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
if (mAdapter == null || mAdapter.getCount() <= 0) {
setScrollingCacheEnabled(false);
return;
}
if (!always && mCurItem == item && mItems.size() != 0) {
setScrollingCacheEnabled(false);
return;
}
if (item < 0) {
item = 0;
} else if (item >= mAdapter.getCount()) {
item = mAdapter.getCount() - 1;
}
final int pageLimit = mOffscreenPageLimit;
if (item > (mCurItem + pageLimit) || item < (mCurItem - pageLimit)) {
// We are doing a jump by more than one page. To avoid
// glitches, we want to keep all current pages in the view
// until the scroll ends.
for (int i=0; i<mItems.size(); i++) {
mItems.get(i).scrolling = true;
}
}
final boolean dispatchSelected = mCurItem != item;
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 {
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
populate(item);
}
}
经过一系列边值判断走到dispatchOnPageSelected(item)
<span style="font-family: Arial, Helvetica, sans-serif; white-space: normal; "><span style="font-size:18px;">看接口OnPageChangeListener是否有被用户实现,有的话执行其中的回调方法。</span></span>
然后回到requestLayout();
该方法的主要作用是:
requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view重 新调用他的onMeasure onLayout来对重新设置自己位置。
详细说明在此:android View中的 requestLayout() 和 invalidate() 原理以及流程
详细说明在此:android View中的 requestLayout() 和 invalidate() 原理以及流程
其实这样子又走回了viewpager的onMeasure 与 onLayout 方法。
又从头审视ViewPager的源码啦!!我的天!!!!!
好吧。。。。。。。
在onMeasure 方法中调用了ViewPager最核心的方法 populate()。。。。。
断点单步执行理解ing.......
详细的源码分析,请移步下面大神简书: