RecyclerView通過Matrix實現(xiàn)視差動畫

這次來實現(xiàn)RecyclerView視差動畫,先來看下效果:

a.gif

那要怎么實現(xiàn)呢?我這里是通過ImageView設(shè)置Matrix實現(xiàn),有更好的辦法歡迎留言告知。
那么Matrix是什么呢?我這里就簡單的說一下,如果想詳細了解的話,請自行搜索查看。

Paste_Image.png

matrix是一個3*3的矩陣,MSCALE_X、MSCALE_Y是來控制綻放的,MSKEW_X,MSKEY_Y是來控制錯切的,MTRANS_X、MTRANS_Y是來控制位移的,MPERSP_0、MPERSP_1MPERSP_2是來控制透視的,MSCALE_XMSCALE_Y、MSKEW_XMSKEW_Y是用來控制旋轉(zhuǎn)的。

那我們要怎么對矩陣操作,可能大家都把線性代數(shù)還回給老師了,就算沒還,算起來也麻煩,所以谷歌給我們提供了方便的方法,分別是preRotate()、setRotate()postRotate,代表的是左乘、設(shè)置和后乘。這之間的差別我就不詳細介紹了。視差效果主要用到了位移和縮放。

那這個效果的思路是怎樣?我們對效果進行拆分,其實發(fā)現(xiàn)每個圖片的效果都是一樣的,滾動后圖片也跟著移動,圖片從RecyclerView頂部到達RecyclerView底部剛好遍歷一整張圖片,頂部時,圖片也顯示頂部。到達底部時,圖片也顯示底部,如圖所示。

圖片在最頂部的效果
圖片在最底部的效果

那我們可以先對這個效果進行分解,在沒有RecyclerView的時候,對ImageView進行圖片的縮放和移動。

首先為ImageView設(shè)置圖片,然后設(shè)置ScapeTypeMatrix,然后根據(jù)圖片比例進行計算,縮放使圖片占滿ImageView,因為我們的圖片是要上下移動,所在我們在放大的時候要在CenterCrop的基礎(chǔ)上保證上下有一部分剩余,這樣才可以移動。并且圖片一開始位于ImageView的頂部。代碼如圖所示:

Paste_Image.png

這里做的事件也很簡單,獲取drawable的原始寬高和ImageView的原始寬高,通過postScale()進行比較縮放,讓圖片占滿整個ImageView這里ImageView的高度乘以1.1主要用于控制縮放后的圖片高度超過ImageView高度的1.1倍。當(dāng)置于recyclerview移動時,讓任何規(guī)格的圖片都可以上下移動,產(chǎn)生較明顯的視差效果。不然的話當(dāng)圖片控件寬高比相同(小于大于和控件圖片比例有關(guān))之類的情況下,會讓圖片上下無法移動。

那我們怎樣對內(nèi)部的圖片進行移動?可以通過postTranslationY()方法對圖片進行上下移動。看,是不是很簡單。

向上移動
a.gif

通過以上的步驟我們已經(jīng)可以控制圖片縮放到正確比例并上下移動,但是我們可以發(fā)現(xiàn)存在一個問題,圖片會被移出ImageView外面。我們可以進行糾正,當(dāng)圖片被移動到ImageView邊框外后,把圖片糾正回ImageView內(nèi)部。代碼如下:

Paste_Image.png

這里主要通過mapRect()方法獲得通過變換后的圖片邊框位置,然后判斷是否超出ImageView的上下邊框,進行糾正,這樣就可能防止圖片移出ImageView的邊框。

a.gif

現(xiàn)在我們已經(jīng)知道怎么圖片怎么通過Matrix進行移動。那實現(xiàn)RecyclerView的視差動畫肯定也難不倒聰明的你,只需要為RecyclerView添加addOnScrollListener()監(jiān)聽,當(dāng)RecyclerView滾動時,根據(jù)每個Item距離RecyclerView頂部的距離移動對應(yīng)的比例。這樣,我們就實現(xiàn)了我們的視差效果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容