什么是svg
SVG是指可伸縮矢量圖形 (Scalable Vector Graphics),它不同于傳統的位圖,不是通過存儲圖像中每一點的像素值來保存與使用圖形,而是通過 XML 文件來定義一個圖形,通過一些特定的語法和規則來繪制出我們所需的圖像
svg的優點很多,簡單講因為存儲的是結構信息而非像素信息,體積小,不失真,不過不太適合層次復雜細節繁多的圖片,畢竟它存儲的相當于是存儲了繪制路徑的關鍵節點和畫筆屬性。svg也是有很多語法,可以實現很多效果和動畫,關于svg的知識可以參考Android SVG技術入門,文章里面也介紹了一些android中解析svg的一些原理,簡言之相當于通過對svg繪制指令的解析,將svg指令對應到Path類中的繪制方法完成繪制,比如svg中的M指令相當于android中的Path.moveTo()。
android中的svg
android中使用svg是通過VectorDrawable,官方介紹鏈接Vector drawables overview。
VectorDrawable是一種定義了點,線,曲線以及它們的顏色信息集合的xml文件。主要優勢就是任意縮放不失真,由此也能減小apk包的大小,因為不必為適配多種分辨率的屏幕添加多套圖片資源。可以直接用xml定義VectorDrawable,也可以從svg文件轉換得到。Android 5.0 (API 21)是官方首次支持VectorDrawable和 AnimatedVectorDrawable的版本,不過低版本的可以使用Android support library兼容。
可以說VectorDrawable是Android中的一種矢量方案,是svg的一種實現,它支持大部分的svg語法。
怎么用?
如果你沒有資源,android studio中提供了一選擇,下面會提到,還有一些網站可以得到免費svg資源:
SVG圖片下載地址
選擇要下載的圖片,下載時選擇svg下載
獲取到的svg文件后,要轉為android中的xml以VectorDrawable的形式使用。可以用工具:
svg2android
能將一個svg圖片轉換成Android中的vector文本。
Android Studio中提供了方便的工具轉換,(如果沒有請升級至最新版,記得升級gradle插件)
android中的使用步驟:
-
res-drawable-new-Vector Asset
vetcor-asset
2.可以選擇android studio自帶的一些vector資源
3.如果有自己的svg資源,可以選擇本地上傳
左下角的Enable auto mirroring for RTL layout指是否支持從右向左布局,使用于從右向左閱讀的語言體系。
4.添加頭像svg后生成的文件:ic_admin.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportHeight="40"
android:viewportWidth="40">
<path android:fillColor="#000000"
android:fillType="evenOdd"
android:pathData="M2,20C2,10.0589 10.0589,2 20,2C29.9411,2 38,10.0589
38,20C38,29.9411 29.9411,38 20,38C10.0589,38 2,29.9411 2,20ZM10.1784,
31.3377C12.4742,30.0084 14.6212,29.3867 14.6212,29.3867C14.6212,29.3867
16.5914,28.8271 16.5914,27.1482C16.5914,26.5559 16.3099,26.0289 16.0285,
25.7491C15.8585,25.5801 14.765,23.9827 13.9252,22.0659C12.6614,21.5192
12.3857,20.5971 12.3857,19.6526C12.3857,19.0841 12.6926,18.8678 12.9647,
18.7878C12.9437,18.5862 12.9325,18.3879 12.9325,18.1939C12.9325,15.1159
12.9774,15.1017 13.0728,13.9633C13.2133,12.629 13.1573,11.092 15.0223,
9.7958C16.8872,8.4997 18.0211,8.5659 19.4438,8.6501C20.376,8.7104 22.6178,
8.6501 23.8114,7.9948C25.005,7.3395 26.7902,11.1296 26.9717,13.5465C27.1532,
15.9634 27.0624,16.5744 26.9717,17.793C26.9717,17.793 26.9545,18.167 26.8726,
18.757C27.1542,18.8268 27.4942,19.0349 27.4942,19.6334C27.4942,20.5551 27.2317,
21.4554 26.0447,22.0064C25.7745,22.691 25.4266,23.3748 24.9791,23.9846C23.1572,
26.4668 23.5532,26.0343 23.4128,26.9265C23.5532,27.6696 22.5923,28.5217 27.3369,
29.9336C28.3379,30.2315 29.2776,30.6097 30.1373,31.0561C33.1263,28.3141 35,24.3759
35,20C35,11.7157 28.2843,5 20,5C11.7157,5 5,11.7157 5,20C5,24.528 7.0063,28.5874
10.1784,31.3377Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>
- vector是VectorDrawable對應的根標簽
- android:width與android:height對應矢量圖的實際大小(矢量圖是可以無限大, 但通常情況下一個圖片都應該有一個原始大小, 假如你將此VectorDrawable作為一個ImageView的src, ImageView的大小都設置為wrap_content, 則ImageView對應的實際大小就是這里設置的大小),由于矢量圖首次加載會消耗更多的CPU資源,建議設置合適的大小以節省繪制時間。
- android:viewportWidth與android:viewportHeight是指當前Drawable對應的虛擬Canvas的大小, 之所以說是虛擬的是因為實際上并不存在這樣一個Canvas, 又之所以需要這個值是因為在 <path/>標簽中的路徑數據要基于具體的坐標系來繪制.
- <path/>標簽對應路徑信息, 這里的path與我們自定義繪制圖形時用的Path原理一樣, 就是記錄一些繪圖操作, 具體對應其中的pathData,PathData中對應的路徑描述符號不需要我們去記, 通常情況下由繪圖軟件生成svg圖片再從svg文件中提取。
- android:fillType對應Path的fillType方法,顏色設置也是,比如android:fillColor是畫筆顏色。可以改變這些屬性然后在旁邊的preview欄里看到實時預覽。
如果不使用android的導入功能,也可以使用其他方式獲取到相應代碼直接定義在xml文件中。
5.使用這個xml,與使用png資源一樣,直接通過drawable引用就可以了。
<ImageView
android:id="@+id/iv_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:src="@drawable/ic_admin"/>
也可以作為drawable檢索
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.iv_user);
有那些坑?
- 小于Api21的低版本適配有兩種方式
- android studio2.2+以及gradle插件1.5.0+下,會自動給低版本生成對應的所有分辨率的png資源,所以這樣會導致apk包比較大,但是可以通過下面的設置要生成的分辨率信息。
defaultConfig {
vectorDrawables.generatedDensities = [edDensities 'hdpi','xxhdpi']
}
2.使用Support Library 23.2+(不會自動生成位圖),Android Support Library 23.2其中主要增加了對VectorDrawable與AnimateVectorDrawable的支持.VectorDrawable可以被兼容到Android2.1, AnimateVectorDrawable可以被兼容到Android3.0
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.2.0'
}
此時,使用的方式會發生變化,比如需要用app:srcCompat來代替android:src。
<ImageView
android:id="@+id/iv_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:srcCompat="@drawable/ic_admin"/>
- 一個處理了android4.0+上svg使用兼容性問題的開源庫:SVG-Android
主要場景
- 圖標各種狀態:修改繪制的顏色
- 圖標+矩形背景,背景各種狀態:修改背景繪制的顏色
- svg可以實現很多酷炫的動畫。可以通過定義AnimateVectorDrawable完成動畫的定義,也可以使用三方庫:PathAnimView