### 1.监听viewpager的touch事件,交换touch的x和y坐标
###2.给viewpager设置pagetransformer
###3.done and enjoy
============================
一屏内显示多页的实现方式有两种,通过给viewpager设置setpagemargin实现和通过覆写pageradapter的getpagewidth实现。
#### 实现方法 通过<code>viewpager.setpagemargin(int marginpixels)</code>,给viewpager的每页设置一个负数的margin,然后在每一页的view留足够的空白给这个负值,来达到一屏显示多页的目的。
#### 原理 如图,此时的viewpager是满屏的大小,通过给viewpager设置负的pagemargin,使得下一页的内容和上一页有了一个重叠区域,而pagecontainer是一个透明的view,作用是留出足够的空白给pagemargin这个值做重叠,为什么说足够的空白,因为还需要考虑到设置pagemargin之后的两页之间的间隔。
使用这个方法会带来一个的体验上的问题(viewpager本身的滑动是有一个判断的,拖动某一页过了一个定值,大概是一页pagecontainer的一半,松手会滑到下一页)向右翻了几页后,向左翻页这个定值会异常,这个值会接近一个pagecontainer的大小,带来的实际体验上的问题是,本来向左稍微滑动可以达到的翻页效果,现在几乎要把这一页完全翻过才能达到,体验上会有一点奇怪。
#### 实现方法 通过重写pageradapter的getpagewidth方法,此方法返回的是viewpager中每一页占实际viewpager的宽度百分比,默认是1,即100%:
相较上一种setpagemargin的方法来说,也许不算个问题,只是和原始viewpager体验上的不一样。通过getpagewidth实现的viewpager,滑动时会始终保持focus的页居左,如图:
而滑动到最后一页时,会有如下图效果,即focus是最后一页时,最后一页不会保持居左,而是会在保证最后一页完全显示的情况下向左滑动一定值,效果及体验见天猫客户端首页。
========================
这里提到的场景比较特殊,一是轮播banner,轮播banner的特点是有一个timer计时器用于计算何时翻到下一页,二是用在了有复用和回收的地方,如listview和recyclerview。
常见的优化是,在viewpager滑出屏幕时需要停止timer,再次滑入屏幕时需要启动timer;需要覆写viewpager里的一些方法实现,但是不一定能都覆盖到,集思广益,先说我暂时收集到的:
这里比较常见的是前三个方法,即在被附加和从window上移除时,可见性发生改变时;
关于后两个方法,先贴源码(取自view.java):
```java /** * this is called when a container is going to temporarily detach a child, with * {@link viewgroup#detachviewfromparent(view) viewgroup.detachviewfromparent}. * it will either be followed by {@link #onfinishtemporarydetach()} or * {@link #ondetachedfromwindow()} when the container is done. */ public void onstarttemporarydetach() { removeunsetpresscallback(); mprivateflags |= pflag_cancel_next_up_event; }
/** * called after {@link #onstarttemporarydetach} when the container is done * changing the view. */ public void onfinishtemporarydetach() { } ```
onstarttemporarydetach和onfinishtemporarydetach是成对出现的方法,在parent需要对此view作出调整的时候会触发onstarttemporarydetach,同时结束后调用onfinishtemporarydetach。