ViewPager PagerAdapter

ViewPager

是负责翻页的一个View,准确的说是一个ViewGroup,包含多个View页,在手指横向滑动屏蔽时,其负责对View进行切换。为了生成这些View页,需要提供一个PagerAdapter来进行数据绑定以及生成最终的View页。

1、setAdapter

ViewPager通过setAdapter()来建立与PagerAdapter的联系。这个联系是双向的,一方面,ViewPager会拥有PagerAdapter对象,从而可以在需要时调用PagerAdapter的方法,另一方面,ViewPager会在setAdapter时,调用PagerAdapter的registerDataSetObserver()方法,成为一个PagerObserver对象,从而在PagerAdapter有所需要时(如notifyDataSetChanged()或notifyDataSetInvalidated()时),可以调用Observer的onChanged()或onInvalidated()方法,从而实现PagerAdapter向ViewPager方向发送信息。

2、dataSetChanged

在PagerObserver.onChanged(),以及PagerObserver.onInvalidate()中被调用。因此当PagerAdapter.notifyDataSetChanged()被触发时,ViewPager.dataSetChanged()也会被触发。该函数将使用getItemPosition()的返回值来进行判断,如果为POSITION_UNCHANGED,则什么都不做,如果为POSITION_NONE,则调用PagerAdapter.destoyItem()来去掉该对象,并设置为需要刷新(needPopulate=true),以便触发PagerAdapter.instantiateItem()来生成新的对象。

PagerAdapter

是ViewPager的支持都,ViewPager将调用它来取得所需显示的页,而PageAdapter也会在数据变化时,通知ViewPager。这个类也是FragmentPagerAdapter以及FragmentStatePagerAdapter的基类。如果继承该类,至少需要实现instantiateItem(), destroyItem(), getCount()以及isViewFromObject()

1、getItemPosition

(1)该函数用以返回给定对象的位置,给定对象是由instantiateItem()的返回值。

(2)在ViewPager.dataSetChanged()中将对该函数的返回值进行判断,以决定是否最终触发PageAdapter.instantiateItem()函数。

(3)在PageAdapter中实现是直接传回POSITION_UNCHANGED。如果该函数不被重载,则会一直返回POSITION_UNCHANGED,从而导致ViewPager.dataSetChanged()被调用时,认为不必触发PagerAdapter.instantiateItem()。

2、instantiateItem

在每次ViewPager需要一个用来显示Object的时候,该函数都会被ViewPager.addNewItem()调用。

3、notifyDataSetChanged()

在数据集发生变化的时候,一般Activity会调用PagerAdapter.notifyDataSetChanged(),以通知PagerAdapter,而PagerAdapter则会通知在自己这里注册过的所有DataSetObserver。其中之一就是在ViewPager.setAdapter()中注册过的PageObserver。PageObserver则进而调用ViewPager.dataSetChanged(),从而导致ViewPager开始触发更新其内含View的操作。

FragmentPagerAdapter

相比通用的PagerAdapter,该类更专注于每一页均为Fragment的情况。该类内的每一个生成的Fragment都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种,如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。FragmentPagerAdapter重载实现了几个必须的函数,我们只需要实现getCount()即可,另外,由于FragmentPagerAdapter.instantiateItem()的实现中,调用了一个新增的虚函数getItem(),因此,我们还需要实现一个getItem()。

1、getItem

(1)该类中新增的一个虚函数。函数的目的为生成新的Fragment对象。在需要时,该函数将被instantiateItem()所调用。

(2)如果需要向Fragment对象传递相对静态的数据时,我们一般通过Fragment.setArguments来进行,这部分代码应当放到getItem()。它们只会在新生成Fragment对象时执行一遍。

(3)如果需要生成Fragment对象后,将数据集里面一些动态的数据传递给该Fragment,那么,这部分代码不适合放到getItem()中。因为当数据集发生变化时,往往对应的Fragment已经生成,如果传递数据部分代码放到了getItem()中,这部分代码将不会被调用。

2、instantiateItem

(1)函数中判断一下要生成的Fragment是否已经生成过,如果生成过了,就使用旧的,旧的将被Fragment.attach(),如果没有,就调用getItem()生成一个新的对象将被FragmentTransation.add()

(2)FragmentPaperAdapter会将所有生成的Fragment对象通过FragmentManager保存起来备用,以后需要该Fragment时,都会从FragmentManager读取,而不会再次调用getItem()方法。

(3)如果需要生成Fragment对象后,将数据集中的一些数据传递给Fragment, 这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用FragmentPagerAdapter.instantiateItem()取得该函数返回的Fragment对象,然后,我们使用Fragment对象中对应的方法,将数据传递过去,然后返回该对象。

3、destroyItem

该函数被调用后,会对Fragment进行FragmentTransaction.detach()。这里不是remove(),只是detach(),因此Fragment还在FragmentManager管理中,Fragment所占用的资源不会被释放。

FragmentStatePagerAdapter

该PagerAdapter的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源。而在页面需要显示时,生成新的页面(就像ListView的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。

1、getItem

(1)该类中新增的虚函数

(2)函数的目的为生成新的Fragment对象。

(3)Fragment.setArguments()这种只会在新建Fragment时执行一次的参数传递代码,可以入在这里。

2、instantiateItem

(1)除非碰到FragmentManager刚好从SavedState中恢复了对应的Fragment的情况外,该函数将调用getItem()函数,生成新的Fragment对象,新的对象将被FragmentTransaction.add().

3、destroyItem

将Fragment移除,即调用FragmentTransaction.remove(),并释放其资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值