天天看點

ViewPager的兩種特殊擴充及其他

### 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。