編輯:關於Android編程
SVG矢量圖在圖片表現力方面遠遠優於PNG位圖,同時在可維護性和修改性方面也比位圖要方便很多。盡管Android在5.0版本就引入了SVG圖片的解決方案:Vector。然而,兼容性和性能方面卻是差強人意,以至於至今都未能廣泛使用。
本篇博客給大家帶來一套較為不錯的解決方案:SVG-Android(作者是本人。。。),相比於Vector,其在兼容性方面能夠兼容到2.3以上,同時在性能方面,也有了質的提升。
開源庫地址:https://github.com/MegatronKing/SVG-Android
PS:主要思想參考的微信的SVG解決方案。
一、SVG-Android為何而生
Android從5.0開始支持SVG圖片,也就是VectorDarwable,但是相比於常用的PNG位圖卻存在著諸多問題。
1、性能方面
正常情況下,Vector的性能損耗是PNG的3倍左右,主要表現在解析xml和計算path兩個階段,如此大的性能差距,導致很少有公司會采用。
2、兼容性
由於android 5.0以上才出現VectorDarwable,為了兼容低版本,google推出了support-vector-drawable兼容庫,但是實際效果並不好。首先,support-vector-drawable兼容庫的最低版本是23.2.0,同時依賴於support-v4,如果support-v4版本過低,無法引入兼容庫。其次,如果要在layout中直接使用vector,必須引入support-v7包,對於不使用v7包的應用來說,只能捨棄vector了。
3、程序包體積
盡管Vector文件相比於PNG圖片,體積占用比較小,但是為了兼容低版本,打包時編譯工具會將vector文件生成對應的PNG圖片一並打包到apk中,這非常容易導致包體積膨脹。
4、實用性
雖然兼容庫能兼容到低版本,但是在API使用方面就不那麼容易了,我們很難直接在xml中直接使用,比如src=”@drawable/svg”,這大大制約了開發效率。
針對以上幾種缺點,SVG-Android應運而生,完美支持2.3+!
二、SVG-Android性能比較
1、SVG-Android VS PNG
SVG-Android在decode階段性能遠遠優於PNG位圖,但是draw渲染階段相對遜色了不少,後期會著力於優化這一塊。
2、SVG-Android VS Vector
SVG-Android在decode階段的性能遙遙領先,耗時大約在100-200us,比Vector高出至少10倍
SVG-Android在draw階段也稍稍領先,大概節約了250us
總體來說,SVG-Android性能方面比PNG位圖略低0.2-0.5倍,比Vector提高了2-3倍。但是對於對圖片效果的呈現,SVG-Android比PNG好很多,完全不會因為尺寸拉伸而失真。
下圖是100次加載的測試數據,單位us,很明顯SVG-Android總體效果還是有優勢的。
三、SVG-Android實現原理
1、預解析
從對Vector的性能測試數據來看,大部分耗時都在解析xml和繪制渲染兩個階段。為了提高性能,SVG-Android的做法是將部分耗時操作由運行時轉移到編譯前,也就是預解析。同時,由於svg文件的fillData的數據在Android中表現為Path,這部分計算量也是可以預先計算好的。
所以,SVG-Generator庫會將Vector文件提前解析生成用於直接渲染的SVGRenderer類,另外fillData的每個指令數也會預先計算好,直接生成Java Path代碼,SVGDrawable只要通過SVGRenderer就能畫出svg圖形了。
2、無感知
為了提高開發效率,我們希望開發者在使用SVG圖片的時候能夠和使用常規的PNG一樣,可以在layout文件中直接使用@drawable/xxx,或者java代碼中使用R.drawable.xxx。為了解決這個問題,我們采用偷天換日的方式,使用SVG-Generator生成一張空的shape文件,放入到drawable-anydpi中,同時會將對應的SVGDrawableConstantState預先注入到Resources的sPreloadedDrawables緩存中,攔截掉所有對shape的獲取請求。
四、SVG-Android如何接入
1、SVG圖片轉換成Vector文件
由於Android只支持部分規范的SVG文件,所以我們還是按照官方的思路,先生成合法的Vector文件,這樣還有個好處就是可以引用dimen和color,方面以後統一修改尺寸和顏色。
SVG圖片轉換成Vector文件有很多種方式。
方式一:使用svg2android網站轉換 http://inloop.github.io/svg2android/
方式二:使用Android Studio 右鍵 -> New -> Vector Asset -> Local SVG File
2、SVG-Generator解析Vector自動生成代碼
首先,在SVG-Generator模塊的Config類中配置好參數:包括應用包名、生成SVGRenderer代碼包名、以及Vector中引用的dimen和color。
其次,在SVG-Generator模塊的build.gradle文件中配置兩個參數:存放Vector文件的目錄,主項目模塊目錄。
接著,運行SVG-Generator的task run。可以在gradle的task列表中點擊,也可以運行命令:gradle task run
最後,我們可以看到在指定的目錄下生成了SVGRenderer類,類名就是圖片名。同時,在drawable-anydpi生成了對應的空shape文件。
3、應用程序中引入SVG-Support包並裝載SVGLoader
在應用程序的Application自定義類中,裝載SVGLoader(上一步自動生成),只要一行代碼!
五、Enjoy SVG-Android!
根據書上教程運行代碼報錯,2.2的黑屏無效果,4.1的閃退。後研究發現,問題出在在一個物體同時啟用了顏色數組和紋理,注釋掉 gl.glEnableClientState
說到圓角濾鏡(效果)很多人會想到app的圖標,沒錯,就是圖標。圓角化的圖片用來做圖標很美觀,這是事實。國人喜愛的iPhone的應用圖標采用的就是圓角化,很多Android
還是先來看看是不是你想要的效果:不廢話,直接上代碼,很簡單,代碼裡都有注釋1 單選public class SingleActivity extends AppCompa
一.引言本篇博客以九宮格手勢解鎖View為例,來說明自定義View如何根據需求處理用戶的手勢操作。雖然九宮格手勢解鎖自定義View網上資料有很多,實現原理大同小異,但這裡