理解PagerAdapter的instantiateItem()方法
在为ViewPager设置Adapter时肯定会用到PagerAdapter,Google Android文档对该类的定义如下:
Base class providing the adapter to populate pages inside of a ViewPager
. You will most likely want to use a more specific implementation of this, such as FragmentPagerAdapter
or FragmentStatePagerAdapter
.
When you implement a PagerAdapter, you must override the following methods at minimum:
instantiateItem(ViewGroup, int)
destroyItem(ViewGroup, int, Object)
getCount()
isViewFromObject(View, Object)
上述四个方法是必须得到重载的,其他的不管,我们今天只看instantiateItem (View container, int position),对于该方法的说明如下:
Parameters
container | The containing View in which the page will be shown. |
---|---|
position | The page position to be instantiated. |
Returns
- Returns an Object representing the new page. This does not need to be a View, but can be some other container of the page.
我的理解是一个Page在切换完成后会调用该方法去加载下一个即将展示的Page,至于是哪个Page取决于切换动作,比如Page1切换到Page2,切换完成后会调用该方法去加载Page3。空说无凭,试着重写该方法打个log出来看看,下面是我重载的instantiateItem()方法:
@Override
public Object instantiateItem(View arg0, int arg1) {
ViewGroup v = (ViewGroup) mListViews.get(arg1).getParent();
if (v != null) {
v.removeView(mListViews.get(arg1));
} else {
Log.i("Allen", String.valueOf(arg1 + 1));
}
((ViewPager) arg0).addView(mListViews.get(arg1), 0);
return mListViews.get(arg1);
}
问题一:是否是真的为即将展示页做操作?
第一句获取父组件后面会说到用处,mListViews定义如下:
mViews = new ArrayList<View>();
mViews.add(viewOne);
mViews.add(viewTwo);
mViews.add(viewThree);
mViews.add(viewFour);
当我从page1->page2->page3->page4->page3->page2->page1,日志如下:
11-07 00:14:38.803: I/Allen(31124): 1
11-07 00:14:38.803: I/Allen(31124): 2
11-07 00:14:56.853: I/Allen(31124): 3
11-07 00:15:00.998: I/Allen(31124): 4
11-07 00:15:05.498: I/Allen(31124): 2
11-07 00:15:07.208: I/Allen(31124): 1
除了第一次进入page1会多打出“1”,其余的切换page操作都会打出"下一次即将显示的页",从page3到page4不会有日志记录,因为没有即将出现在page4之后的页。
因此问题一的答案是肯定的。
问题二:为什么要获取父组件?
这个操作后来检查发现是不必要的,出现这个操作的原因是我在设置Adapter之前做了如下操作:
mPager = (ViewPager) findViewById(R.id.guide_pager);
mPager.addView(viewOne);
mPager.addView(viewTwo);
mPager.addView(viewThree);
mPager.addView(viewFour);
如果不获取父组件并对子view进行remove操作,会报如下错误
java.lang.IllegalStateException The specified child already has a parent. You must call removeView() on the child's parent first.
这个操作打出的日志也是不同的,同样是page1->page2->page3->page4->page3->page2->page1,日志如下:
11-07 00:28:11.158: I/Allen(1688): 2
11-07 00:28:13.963: I/Allen(1688): 1
这是因为在第一次page1到page4的切换过程中,4个page早已被加到pager中,所以第一次进入page1打印的“1”和“2”,page2的“3”以及page3的“4”是不会打印出来的,只有page3的“2”和page2的“1”。由此我猜想pager对page做了窗口处理,窗口长度大小为3,即始终保存当前page,切换前page和即将切换page。
读者完全不必采用笔者提前为Pager添加addView的处理,如果这样处理就要及时从父组件中移除view
理解PagerAdapter的instantiateItem()方法的更多相关文章
- 深度理解Jquery 中 offset() 方法
参考原文:深度理解Jquery 中 offset() 方法
- Java反射理解(五)-- 方法反射的基本操作
Java反射理解(五)-- 方法反射的基本操作 方法的反射 1. 如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法 2. 方法反射的操作 method.invoke(对象,参数列表) ...
- PagerAdapter instantiateItem()方法position错误解决方案
异常信息:java.lang.IndexOutOfBoundsException: index=3 count=2 在instantiateItem各个条目View的时候.会有 container.a ...
- 【Android进阶】关于PagerAdapter的使用方法的总结
PagerAdapter简介 PagerAdapter是android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAdap ...
- Android——关于PagerAdapter的使用方法的总结(转)
PagerAdapter简介 PagerAdapter是android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAdap ...
- 深入理解javascript的getTime方法
1.理解getTime getTime() 方法返回一个时间的格林威治时间数值. 可以使用这个方法把一个日期时间赋值给另一个Date 对象. 语法: dateObj.getTime() 参数: 无. ...
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/19996629 开篇 在我的上一篇博客 深入理解Java中为什么内部类可以访问外部类的成 ...
- 理解jquery的.on()方法
jquery在的.on()方法用来给元素绑定事件处理函数的,我经常用在两个地方: 给未来的元素绑定事件:我总是这样用:$(document).on('click','#div1',function() ...
- 读取本地文件理解FileReader对象的方法和事件以及上传按钮的美化。
一.FileReader对象 用来把文件读入内存,并且读取文件中的数据.FileReader对象提供了异步API,使用该API可以在浏览器主线程中异步访问文件系统,读取文件中的数据. 浏览器支持情况, ...
随机推荐
- Python中操作mysql的pymysql模块详解
Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...
- ABAP 订单-交货单-发货过账自动完成 案例
*&---------------------------------------------------------------------* *& Report ZSDR006 ...
- java内存溢出和内存泄露
虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 最近在网上搜集了一些资料,现整理如下: —————————————————————————————————————— ...
- OpenGL中坐标系的理解(一)
在OpenGL中,存在着至少存在着三种矩阵,对应着函数glMatrixMode()的三个参数:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 以下主要描述GL_MODEL ...
- ModelMapper 中高级使用 java
ModelMapper 是一个java对象自动映射的第三方架包,用起来很方便,配合阿里的frstjson可以极大简化后台代码. 但是ModelMapper 中文使用说明很少,官网http://mode ...
- Tomcat绑定IPV4端口
使用下面的方法可以绑定到IPV4, 在<tomcat>/bin目录下新建setenv.sh,如果没有话,然后添加如下内容: JAVA_OPTS="$JAVA_OPTS -Djav ...
- Werkzeug工具包学习-官方例子Shortly分析
为了学习werkzeug的wsgi框架工具,今天真对官网的例子进行调试运行.涉及到了werkzeug工具包,jinja2前端模版,以及redis内存库,之后可以灵活定制自己主页.再次,作以记录. 首先 ...
- Destroying The Graph(poj 2125)
题意: 给你一张有向图,你可以选择一个点:• 摧毁其所有的入边,代价A[i].• 摧毁其所有的出边,代价B[i].• 求摧毁这张图的最小代价.• 数据范围1000 /* 很经典的一道题目(我这么弱,稍 ...
- Swift - UIBezierPath
使用UIBezierPath可以创建基于矢量的路径.使用此类可以定义简单的形状,如椭圆.矩形或者有多个直线和曲线段组成的形状等.主要用到的该类的属性包括 moveToPoint: //设置起始点 ad ...
- 使用Solr索引MySQL数据
环境搭建 1.到apache下载solr,地址:http://mirrors.hust.edu.cn/apache/lucene/solr/ 2.解压到某个目录 3.cd into D:\Solr\s ...