Recyclerview下拉刷新干貨(自定義)
今天無聊看看csdn,看到了篇好有 啟發的部落格,因為RecyclerView是我們開發中不可避免的會用到的(可以說用到機率100%),這篇乾貨看了啟發很大啊。再也不愁自定義重新整理介面了。看嚴大大部落格果然每次都受益匪淺 = =
老樣子,開頭先來句居里夫人的名言,是我網上找的,感覺啟發性很大。轉載收藏Make下。
——— 居里夫人
下拉重新整理視差動畫也是這幾天公司的一個動畫,今晚終於不用加班了,加上好多小夥伴問我這個效果,就把這個動畫用部落格的形式介紹給大家吧,對了如果你想和我交流更多,可以加我部落格聯絡方式中的QQ群。
首先要說明,今天講的是自定義下拉重新整理動畫,不是下拉重新整理框架怎麼寫,所以就算不是你想要的,你看看也無防哈哈哈哈……
效果重新整理
Ultra-Pull-To-Refresh下拉重新整理庫的介紹
推薦這個庫是一方面是因為PullToRefresh
的停止更新,另一方面是Ultra-Pull-To-Refresh
的合理設計,滿足了我所有的幻想,它唯一的不足是:當頂部巢狀類似ViewPager
這種左右滑動的View
時下拉重新整理會變的很靈敏,多使用者體驗不太好,不過這一點我已經給出了一個臨時解決方案,如果要知道詳情請移步此部落格:
http://blog.csdn.net/yanzhenjie1003/article/details/51319181。
不過今天的部落格中的庫我已經把修復了的原始碼附上了,所以大家也可以看完本文後直接下載所有原始碼。
自定義動畫的分析
首先是Ultra-Pull-To-Refresh
的特點,此庫提供了一個Layout
類:PtrFramLayout
作為Wrapper
來包涵ContentView
,今天用到兩個方法:第一個PtrFramLayout#setHeaderView(View)
用來設定頭部顯示的重新整理View,第二個PtrFramLayout#addPtrUIHandler(PtrHandler)
用來設定監聽使用者下拉狀態、下拉offset
、重新整理完成狀態等。
其次是動畫的,根據效果圖,第一點是下拉的時候人物從左側走過來到中間,到中間後手指再繼續往下拉,此時人物也不走了,第二點是當手指鬆開時或者處於下拉狀態時,人物不停的走動,並且背景產生一個相對位移,給人的視覺上造成一個視覺差,也就是我們想要的視差動畫了,這就是整個視差動畫的實現步驟。
那麼幾個動畫拆分開來就是,人物向右中間移動、人物原地踏步、背景無限向左移動。
頭View和重新整理Layout的實現
我把實現步驟分開講解,方便讀者理解:
- 實現自定義的頭View。
- 繼承
PtrFramLayout
實現一個ParallaxPtrFrameLayout
,設定自定頭和PtrHandler
監聽下拉動作。 - 實現人物向左走的動畫。
- 鬆開手時背景不停的向右移動,人物在原地邁步,形成一個視差上的向右走的動畫。
自定義頭部View
頭View的底下是這樣一個圖:
那麼一個圖是如何做到不停的向左移動還是無限重複的呢?用HTML做很簡單,但是Android中並沒有repeat這樣的屬性,於是我們想到:在螢幕上放一個ImageView
向左移動100%,在這張圖的右側再放一個ImageView
,以同樣的速度向左移動100%,結果就是當螢幕上的圖移動到左邊外螢幕的時候,螢幕右邊的圖剛好移動到螢幕上完全顯示,然後我們的動畫又有重複播放的屬性,結合起來就產生了一個背景無限長的動畫效果。對於人物原地踏步就很簡單了,直接用一個ImageView
不停的切換圖形成一個人物在走動的視覺效果。
所以我們用兩個ImageView
作為背景圖來相間向左移動,用一個ImageView
不停的切換圖模擬人物走動,來達到一個人物走動的視差效果,我打算用FrameLayout
來作為頭View
的Layout
,所以佈局用merge
包裹了一下:
refresh_parallax.xml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
然後定義頭View
載入剛才寫好的佈局,因為PtrFrameLayout
是通過PtrHandler
介面來監聽下拉狀態和重新整理狀態,然後以狀態為依據來重新整理頭View的動畫,所以頭View直接實現PtrHandler
介面,然後操作自身的狀態和動畫也就更加方便了,所以頭View初步的程式碼是:
ParallaxHeader
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
裡面的程式碼很簡單,就是載入剛才定義好的頭View
對應的Layout.xml
檔案,然後把兩個背景View
和人物View
給找出來。頭View
定義好了,接下來定義重新整理的Layout
。
實現ParallaxPtrFrameLayout載入頭View
Ultra-Pull-To-Refresh
的重新整理Layout
都是繼承PtrFramLayout
,然後設定頭View
和重新整理狀態監聽等,所以我們定義一個ParallaxPtrFrameLayout
繼承PtrFrameLayout
,在裡面設定頭View
和PtrHandler
等來回調操作的頭View
的動畫,很簡單的幾行程式碼:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
由於Ultra-Pull-To-Refresh
的合理設計,到這裡為止,我們的頭View
和重新整理的Layout
就完成了,接下來就專心研究動畫吧。
動畫的實現
上文也提過了,這裡的動畫拆分開幾個,一是下拉的時候人物向右中間移動,二是重新整理的時候人物不停的原地踏步,三是重新整理的時候背景一個向左平移,為了方便理解,這裡把下拉時候人物向右中間移動放到最後來講。
一、人物原地踏步動畫
首先想到的就是幀動畫,沒錯就是這傢伙,用幀動畫可以做到每多少時間換一張圖片,所以我們的人物有三張不同的動畫,不停的切換就形成了一個人物走動並車輪轉動的效果:
我們用幀動畫控制每張圖顯示100毫秒,然後就切換下一張圖,這樣便達到我們說的人物走動的效果了,用xml來實現:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
因為這是一個幀動畫,需要在程式碼中觸發,所以我們要把這個動畫放在drawable
資料夾,並且把這個drawable
當圖片設定頭View
中的人物ImageView
:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
二、背景無限向左移動
這個動畫就厲害了word哥,當時我先做出來,然後給iOS的同學講實現的原理,他還是花了點時間來理解的,所以我再費點口舌解釋一下。
這裡是兩個ImageView
,一個在螢幕正中央,並且佔據整屏寬,一個在螢幕外的右側,寬度等於螢幕寬度。動畫開始時,螢幕上的ImageView
開始一步步向左移動100%,螢幕之外的ImageView
以同樣的速度向左移動100%,當螢幕上的ImageView
移動到左邊外螢幕的時候,螢幕右邊的圖剛好移動到螢幕上完全顯示,然後我們的動畫又有重複播放的屬性,結合起來就產生了一個背景無限長的動畫效果。
為了方便大家理解,我畫了一張圖:
圖是畫