SnakeMaker:模仿實現 即刻APP 頭像拖動的殘影效果

一直比較喜歡即刻APP的交互效果,作為一個比較注重交互體驗的安卓開發愛好者,自然不免會關注它的交互體驗以及實現方式。其中的頭像拖動效果一直讓我覺得挺有意思:

https://www.zhihu.com/video/927920856120823808

頭像拖動時會產生殘影,拖動結束時殘影也會慢慢消失。最初看到這種效果就被吸引了,一直沉迷於思考如何實現這種效果。但實在是太懶,經常思考出實現方式後就頓覺無味,失去興趣,轉而去沉迷下一個奇淫技巧了。最近忽然痛定思痛,決心也寫點什麼東西,抖點所謂的乾貨出來,分享於世,也不枉轉行做了這麼久的開發,首先想寫的就是這種效果了。

拖動效果挺像遊戲里的貪吃蛇的,所以我起了個名字 SnakeMaker,先看一下我做的效果:

https://www.zhihu.com/video/927926924255313920

跟即刻的效果基本上一致。下面來分享一下實現思路。

安卓開發中View的位置依賴於其父容器,因此也只能在其父容器限定的區域里顯示。這樣就帶來一個問題:如果想要實現目標View在整個屏幕區域里拖動,其父容器的尺寸要和屏幕尺寸相同。但實際開發中,創建布局時,很多時候我們不能保證目標view的父容器和屏幕尺寸一樣。那麼有沒有方法解決這個問題呢?

當然有解決的方式了。為了保證可以對Activity或Fragment的布局裡的任何一個子view做出這種拖動效果,必須繞過上述的問題。如果我們不直接操作目標view,而是複製一個和目標view一摸一樣的copyView,然後將copyView添加到一個和屏幕尺寸一樣大的ViewGroup里,接著操作copyView的拖動,這樣就不受目標view位置的限制了!沒錯,就是一種偷梁換柱,瞞天過海的方法。所以我得實現實現思路是這樣子的:

1.當Activity或Fragment的布局載入完畢後,獲取目標view的信息(尺寸,背景圖,屏幕中的位置等)

2. 複製多個目標view。一個作為頭,剩餘的作為殘影。

3.處理複製的view(殘影透明度,監聽綁定等),然後添加到指定的ViewGroup里(ViewGroup的尺寸最好覆蓋整個屏幕,這樣可以在整個屏幕里拖動)。

4.隱藏目標view,處理複製view的拖動效果。

以上便是整個實現思路。通過這樣的處理,我們可以包裝布局裡任意一個子view,給其添加這種拖動效果。具體的代碼細節就不講了,上面步驟中沒有太難實現的地方,重要的是分享思路。文後會給出github地址。簡單看一下如何使用:

SnakeViewMaker snakeViewMaker = new SnakeViewMaker(MainActivity.this);
snakeViewMaker.addTargetView(imageView) // 綁定目標View
.attachToRootLayout((ViewGroup) findViewById(R.id.root));// 綁定Activity/Fragment的根布局

attachToRootLayout(ViewGroup root)方法可以將這種效果綁定到任何一個指定的容器里(Linearlayout除外)。當然,如果不指定的話會默認綁定到Activity的根布局裡(android.R.id.content)。

一個需要注意的地方是,如果目標view載入的圖片是網路圖片,在綁定目標view時,網路圖片可能還沒有載入完成,因此需要在網路圖片載入完成後再對目標view綁定。

在我最近開發的兩個app里,已經使用了這個效果,用下來感覺還不錯,絕大部分場景都能完美實現。當然了,和即刻的效果相比,還是有一個特別細小的差別。等我有時間解決的這一細小差別,再來分享心得。

具體的API使用就不詳寫了,感興趣的話歡迎去github上指教。源碼也很簡單,實現這樣的效果不到四百行,如果你發現了問題,也歡迎指正。

guthub地址:SnakeViewMaker

推薦閱讀:

TAG:Android開發 | 即刻(App) | 交互設計 |