媲美掘金App大圖瀏覽效果,你確定不看一下?
大圖瀏覽幾乎是App必備功能,因為一般列表展示的圖片,考慮到效能,速度以及伺服器頻寬的問題,都是壓縮過的縮圖。如果使用者想看詳細的大圖,則需要點選圖片進入大圖瀏覽介面。
大圖瀏覽介面怎麼做?
粗略的我們可以用一個對話方塊,裡面放ViewPager,然後縮放用PhotoView。以前我也是這麼幹的。但這麼做是不符合Material Design設計的,因為介面之間的切換太突兀,沒有如絲般順滑的過渡效果。
無圖言Diao
來看下我實現的效果:



之前在Android端目前我覺得大圖瀏覽體驗最好的就是掘金App的效果,我這個應該可以媲美掘金的效果了。真實體驗你會發現,可能比掘金的更流暢,更絲滑。
原理分析
原理上有幾個點:
- 圖片之間的過渡
圖片之間的過渡是指小圖到大圖的過渡,中間沒有任何的跳躍變化,需要是絲滑而自然的過渡。這個要考慮的使用者的ImageView有可能是各種的ScaleType。對於任意的ScaleType如何實現完美的過渡呢?
答案只有一個,就是: Martirx。
因為無論ImageView的ScaleType是什麼,最終都會計算出一個DrawMartix,它表示圖片的畫素矩陣。所以對Martix進行過渡才是正確的,這過程中我探索了很多方案,比如寬高,手動計算Martix。
至於具體怎麼對Martix進行過渡,我們可以很容易寫出一個ValueAnimator,也可以用系統的ChangeImageTransform來做。我選擇的是後者。具體看原始碼吧。
- 介面之間的過渡
介面之間的過渡,指的是從呼叫者的介面過渡到大圖介面。這其實是一個彈窗效果,它主要伴隨著背景明暗的漸變,這個很容易實現。你可以用PopupWindow,Dialog,或者whatever。我是直接依靠XPopup(我的一個彈窗庫)提供的彈窗實現。
- 可拖拽的容器
從動圖中可以看到,大圖瀏覽可以通過點選關閉,也可以通過手勢上下滑動關閉。可拖拽的容器實現起來並不難,可以自己操作TouchEvent,也可以用ViewDragHelper。我比較喜歡後者。核心的拖拽程式碼其實不超過50行。
單單拖拽很好做,但是涉及到ViewPager和裡面的PhotoView就有點麻煩了。需要處理好跟ViewPager的滑動優先選擇,還要PhotoView是否可以允許外界拖拽。更細節的東西可以看程式碼。
如何使用
上面的效果,我直接內建在XPopup中,提供一個封裝。使用起來也就是這樣:
XPopup.get(getContext()).asImageViewer(imageView, position, list, new OnSrcViewUpdateListener() { @Override public void onSrcViewUpdate(ImageViewerPopupView popupView, int position) { // 作用是當Pager切換了圖片,需要更新源View popupView.updateSrcView((ImageView) recyclerView.getChildAt(position)); } }).show(); 複製程式碼
具體使用請檢視: github.com/li-xiaojun/…
最後:曾經的Android開發很難,為簡化Android開發貢獻一份小小的力量。