上下滑切換翻頁大概是這樣的效果:git
目前網上有諸多如 「仿抖音上下滑...」 「仿花椒映客直播...」 之類的技術分享,都有講述實現上下滑切換頁面的方案,其中以 ViewPager
和 RecyclerView
+ SnapHelper
兩種方案爲多,可是都有明顯的缺點。如下是一些我的的見解:github
ViewPager
自帶的滑動效果徹底知足場景,並且支持 Fragment
和 View
等UI綁定,只要對佈局和觸摸事件部分做一些修改,就能夠把橫向的 ViewPager
改爲豎向。佈局
可是沒有複用是個最致命的問題。在 onLayout
方法中,全部子View會實例化並一字排開在佈局上。當Item數量很大時,將會是很大的性能浪費。性能
其次是可見性判斷的問題。不少人會覺得 Fragment
在 onResume
的時候就是可見的,而 ViewPager
中的 Fragment
就是個反例,尤爲是多個 ViewPager
嵌套時,會同時有多個父 Fragment
多個子 Fragment
處於 onResume
的狀態,卻只有其中一個是可見的。除非放棄 ViewPager
的預加載機制。在頁面內容曝光等重要的數據上報時,就須要判斷不少條件:onResumed
、 setUserVisibleHint
、 setOnPageChangeListener
等。動畫
最後是嵌套滑動的問題。同向嵌套滑動是很常見的場景,Google 新出的滑動佈局基本都使用 NestedScrolling 機制來解決嵌套滑動。可是 ViewPager 依然須要開發者本身來處理複雜的滑動衝突。code
RecyclerView
+ SnapHelper
的方案比 ViewPager
好得多,既有對 View
的複用,滑動事件也已經處理好。cdn
可是依然沒法雙向無限滑動。咱們能夠在 getItemCount
方法中返回 Integer.MAX_VALUE 來僞裝無限個滑動元素。可是爲了從頭開始就能夠下拉滑到上一個,元素列表的索引就不能初始化爲0,那初始值爲 Integer.MAX_VALUE/2 ? 不管怎麼掩飾,理論上仍是有滑動到頭的一天。索引
使用兩個 View 輪流切換就能完成上下滑的場景。這種方案也有APP在用,可是網上幾乎找不到源碼。所以我把它抽成獨立的庫放在Github倉庫:致力於打造通用、易用和流暢的上下滑動翻頁佈局SlidableLayout。接口
SlidableLayout 本質是一個包含兩個相同大小子 View
的 FrameLayout
。兩個子 View
分別做爲 TopView 和 BackView 。事件
靜止狀態下,用戶只會看見 TopView ,而 BackView 被移除或隱藏。
手指向上拖動時, TopView 在y軸上向上偏移, BackView 開始出現,並且 BackView 的頂部與 TopView 的底部相接。
手指向上拖動必定距離後放手,TopView 繼續在y軸上作動畫直到徹底消失, BackView 向上直到徹底出現。而後 TopView 和 BackView 互換身份,原來的 BackView 成爲如今的 TopView ,原來的 TopView 被移除或隱藏,成爲下一次滑動的 BackView 。互換後完成一次滑動。
反之,手指向下滑動亦然。
同時要考慮手指放手後,滑動距離不夠或者速度不夠時,TopView 會沿着y軸回彈到原來的位置。 BackView 也跟着原路返回,直到被移除或隱藏。
SlidableLayout 還實現了 NestedScrollingChild 接口,使其可以與自定義的下拉刷新佈局嵌套滑動。
源碼和使用例子參照 github.com/YvesCheung/… 。若有不一樣意的地方,請在 Github 留下 Issue。