理解PagerAdapter的instantiateItem()方法
2016-03-16 22:45
351 查看
在为ViewPager设置Adapter时肯定会用到PagerAdapter,Google Android文档对该类的定义如下:
Base class providing the adapter to populate pages inside of a
When you implement a PagerAdapter, you must override the following methods at minimum:
上述四个方法是必须得到重载的,其他的不管,我们今天只看instantiateItem (View container, int position),对于该方法的说明如下:
Parameters
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()方法:
问题一:是否是真的为即将展示页做操作?
第一句获取父组件后面会说到用处,mListViews定义如下:
当我从page1->page2->page3->page4->page3->page2->page1,日志如下:
除了第一次进入page1会多打出“1”,其余的切换page操作都会打出"下一次即将显示的页",从page3到page4不会有日志记录,因为没有即将出现在page4之后的页。
因此问题一的答案是肯定的。
问题二:为什么要获取父组件?
这个操作后来检查发现是不必要的,出现这个操作的原因是我在设置Adapter之前做了如下操作:
如果不获取父组件并对子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,日志如下:
这是因为在第一次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
转载连接:http://www.cnblogs.com/AllenWen/p/4080296.html
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
FragmentPagerAdapteror
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,日志如下:
因此问题一的答案是肯定的。
问题二:为什么要获取父组件?
这个操作后来检查发现是不必要的,出现这个操作的原因是我在设置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,日志如下:
读者完全不必采用笔者提前为Pager添加addView的处理,如果这样处理就要及时从父组件中移除view
转载连接:http://www.cnblogs.com/AllenWen/p/4080296.html
相关文章推荐
- mac系统下MySQL5.7.11安装版密码问题
- TOJ 2891."Sub"-Sequence
- POJ1699 Best Sequence(AC自动机+状压DP)
- 单机搭建Android开发环境(五)
- postgresql - 事务
- 目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点?
- Java动态性之--反射机制
- PHP中的魔术常量、预定义常量和预定义变量
- CenOS6.5上matplotlib的show函数不能显示图片的问题
- java 错误:找不到或无法加载主类
- java删除文件夹
- 元素节点、属性节点
- 四则运算
- UITableView的简单用法
- linux内核分析 1、2章读书笔记
- iOS关于UITabView和UIAlertController,UIAlertAction以及UINavigation,值修改的传递页面推送
- DFS BFS 路径记录的总结
- css布局模型
- C++ .csv文件处理 与 sstream应用
- Android开发属性动画