为什么我不用ViewPager或RecyclerView来做上下滑切换
上下滑切換翻頁大概是這樣的效果:
目前網上有諸多如 “仿抖音上下滑...” “仿花椒映客直播...” 之類的技術分享,都有講述實現上下滑切換頁面的方案,其中以 ViewPager 和 RecyclerView + SnapHelper 兩種方案為多,但是都有明顯的缺點。以下是一些個人的看法:
為什么ViewPager不合適
ViewPager 自帶的滑動效果完全滿足場景,而且支持 Fragment 和 View 等UI綁定,只要對布局和觸摸事件部分作一些修改,就可以把橫向的 ViewPager 改成豎向。
但是沒有復用是個最致命的問題。在 onLayout 方法中,所有子View會實例化并一字排開在布局上。當Item數量很大時,將會是很大的性能浪費。
其次是可見性判斷的問題。很多人會以為 Fragment 在 onResume 的時候就是可見的,而 ViewPager 中的 Fragment 就是個反例,尤其是多個 ViewPager 嵌套時,會同時有多個父 Fragment 多個子 Fragment 處于 onResume 的狀態,卻只有其中一個是可見的。除非放棄 ViewPager 的預加載機制。在頁面內容曝光等重要的數據上報時,就需要判斷很多條件:onResumed 、 setUserVisibleHint 、 setOnPageChangeListener 等。
最后是嵌套滑動的問題。同向嵌套滑動是很常見的場景,Google 新出的滑動布局基本都使用 NestedScrolling 機制來解決嵌套滑動。但是 ViewPager 依然需要開發者自己來處理復雜的滑動沖突。
為什么RecyclerView不合適
RecyclerView + SnapHelper 的方案比 ViewPager 好得多,既有對 View 的復用,滑動事件也已經處理好。
但是依然無法雙向無限滑動。我們可以在 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。
轉載于:https://juejin.im/post/5cd185e5e51d456e6479b528
總結
以上是生活随笔為你收集整理的为什么我不用ViewPager或RecyclerView来做上下滑切换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DEVEXPRESS---TREELIS
- 下一篇: Java虚拟机-第二篇-GC算法与内存分