码迷,mamicode.com
首页 > 其他好文 > 详细

关于PagerAdapter的instantiateItem()方法的理解

时间:2014-11-07 06:06:38      阅读:600      评论:0      收藏:0      [点我收藏+]

标签:des   android   style   blog   io   color   ar   os   java   

 

在为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 asFragmentPagerAdapter 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()方法的理解

标签:des   android   style   blog   io   color   ar   os   java   

原文地址:http://www.cnblogs.com/AllenWen/p/4080296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!