ViewPager部分源码分析一:加载数据
onMeasure()调用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()方法了么!!
ViewPager部分源码分析一:加载数据的更多相关文章
- Spring Boot源码分析-配置文件加载原理
		
在Spring Boot源码分析-启动过程中我们进行了启动源码的分析,大致了解了整个Spring Boot的启动过程,具体细节这里不再赘述,感兴趣的同学可以自行阅读.今天让我们继续阅读源码,了解配置文 ...
 - mybatis源码分析--如何加载配置及初始化
		
简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...
 - 精尽Spring Boot源码分析 - 配置加载
		
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
 - Spring源码分析之-加载IOC容器
		
本文接上一篇文章 SpringIOC 源码,控制反转前的处理(https://mp.weixin.qq.com/s/9RbVP2ZQVx9-vKngqndW1w) 继续进行下面的分析 首先贴出 Spr ...
 - 第一次源码分析: 图片加载框架Picasso源码分析
		
使用: Picasso.with(this) .load("http://imgstore.cdn.sogou.com/app/a/100540002/467502.jpg") . ...
 - 源码分析: 图片加载框架Picasso源码分析
		
使用: Picasso.with(this) .load("http://imgstore.cdn.sogou.com/app/a/100540002/467502.jpg") . ...
 - 1.Sentinel源码分析—FlowRuleManager加载规则做了什么?
		
最近我很好奇在RPC中限流熔断降级要怎么做,hystrix已经1年多没有更新了,感觉要被遗弃的感觉,那么我就把眼光聚焦到了阿里的Sentinel,顺便学习一下阿里的源代码. 这一章我主要讲的是Flow ...
 - springboot集成mybatis源码分析-启动加载mybatis过程(二)
		
1.springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplication中的@EnableAutoConfiguration 2.EnableAuto ...
 - JDBC源码分析(加载过程)
		
public static void main(String[] args) { String url = "jdbc:mysql://172.16.27.11:3306/jdbcT ...
 - Mybatis源码解析(二) —— 加载 Configuration
		
Mybatis源码解析(二) -- 加载 Configuration 正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...
 
随机推荐
- win32程序组成
			
程序代码+UI资源——RC编译器整合——>EXE档案. UI资源:二进制代码(借助工具产生,并以各种扩展名的文件存在),程序员必须在资源描述文档(.rc)中描述他们. RC编译器(RC.EXE) ...
 - python 输入和输出
			
到目前为止我们遇到过两种输出值的方法: 表达式语句和print语句. (第三个方式是使用文件对象的write()方法: 标准输出文件可以引用 sys.stdout.详细内容参见库参考手册. Pytho ...
 - Cocos2d-x 3.0 Json用法     Cocos2d-x xml解析
			
Cocos2d-x 3.0 加入了rapidjson库用于json解析.位于external/json下. rapidjson 项目地址:http://code.google.com/p/rapidj ...
 - git  教程(11)--从远程库克隆
			
上次我们讲了先有本地库,后有远程库的时候,如何关联远程库. 现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆. 首先,登陆GitHub,创建一个新的仓库,名字叫gitskill ...
 - Caffe学习系列(14):Caffe代码阅读
			
知乎上这位博主画的caffe的整体结构:https://zhuanlan.zhihu.com/p/21796890?refer=hsmyy Caffe 做train时的流程图,来自http://caf ...
 - git 使用入门篇
			
最近准备给同事培训git,发现了一个不错的资源,在这里:http://www.gitguys.com/topics/creating-a-shared-repository-users-sharing ...
 - 蓝牙模块连接后出现ANR,日志记录
			
11-25 16:29:48.433 14507-14561/myapplication.com.myblue W/MALI: glDrawArrays:714: [MALI] glDrawArray ...
 - IntelliJ IDEA License
			
http://jetbrains.tech/ http://jetbrains.tencent.click/
 - MD5 加密字符串
			
public class MD5 { /*** * MD5加码 生成32位md5码 */ public static String string2MD5(String inStr){ MessageD ...
 - JAVA8 十大新特性详解
			
前言: Java8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章, 例如Playing with Java ...