理解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可以在浏览器主线程中异步访问文件系统,读取文件中的数据. 浏览器支持情况, ...
随机推荐
- 49. 3种方法实现复杂链表的复制[clone of complex linked list]
[本文链接] http://www.cnblogs.com/hellogiser/p/clone-of-complex-linked-list.html [题目] 有一个复杂链表,其结点除了有一个ne ...
- phpstudy 80端口被占用,修改端口
搭建mantis,总会出现80端口被占用的情况.看到别的步骤是:1.cmd 运行netstat -ano查看80端口被什么占用,然后在任务管理器找到对应的结束进程.通常情况下是被System占用,右击 ...
- Debian8.3如何设置默认不启动Gnome
最近又光荣的回归了debian的怀抱,其实我就是跟风,现在做传媒平时也用不到多么高深的计算机知识,纯粹自己瞎鼓捣……嘿嘿,我相信有很多像我一样的人,刚刚装上了debian可以在同事面前华丽丽的装了一逼 ...
- 将页面转化为pdf的实现方法
1.实现代码把html转化为pdf主要是使用wkhtmltopdf.exe工具生成,在获取转化的地址,创建一个进程,把地址传递到进程参数中进行调用wkhtmltopdf.exe工具打印 2.代码片段/ ...
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- oracleDBA-D2
1.超级管理员sys和system的区别: sys权限比system大,system无法查看到当前数据库是否运行在归档模式下,无法关闭数据库.sys是老大,system是老二. 2.OEM-oracl ...
- (转载)org.springframework.web.context.ContextLoaderListener
http://www.yihaomen.com/article/java/471.htm 刚才手贱乱点了下,然后好像jar包不见了还是什么的,出现了这个错误,按照帖子说的,手动添加maven进去就好了
- Js中 md5 sha1 base64 加密
js的3中加密方式: .sha1加密,加密性高 调用: var sha = hex_sha1(str); .base64加密 调用: var b = new Base64(); var str = b ...
- webkit 模拟点击 winform
刚在园子里看到有博主将WebBowser控件替换为Chrome内核(),链接http://www.cnblogs.com/gdyblog/p/WebKitBrowser.html 于是我想既然实现了替 ...
- sqlserver中BCP命令导入导出
个人自用导出文本文件命令: bcp [xxDB].[dbo].[xx_tb_name] out d:\temp\xxx.txt -c -t "\t" -T bcp是SQL Serv ...