SVG的全稱是Scalable Vector Graphics,叫可縮放矢量圖形。它和位圖(Bitmap)相對(duì),SVG不會(huì)像位圖一樣因?yàn)榭s放而讓圖片質(zhì)量下降。它的優(yōu)點(diǎn)在于節(jié)約空間,使用方便。
android也在5.0中新增了對(duì)使用svg矢量圖支持,現(xiàn)在網(wǎng)上也有大把關(guān)于svg的文章但是使用時(shí)還是有遇到了許多坑,所以在這里我就總結(jié)了下我在使用svg過(guò)程中遇到的各種坑,希望對(duì)大家有所幫助。
VectorDrawable
要想在Android使用svg,首先要介紹的肯定是VectorDrawable,VectorDrawable是Android 5.0系統(tǒng)中引入了 VectorDrawable 來(lái)支持矢量圖(SVG),同時(shí)還引入了 AnimatedVectorDrawable 來(lái)支持矢量圖動(dòng)畫(huà)。
官方文檔:
VectorDrawable,AnimatedVectorDrawable
VectorDrawable轉(zhuǎn)換Bitmap
Bitmap bitmap;
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){
Drawable vectorDrawable = context.getDrawable(R.id.img_vector);
bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
}else {
Drawable drawable = AppCompatDrawableManager.get().getDrawable(context, R.id.img_vector);
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
5.0以上版本使用
Android studio在2.0的版本中可以直接使用svg
新建一個(gè)SVGDemo項(xiàng)目,
**新建Vector Asset文件 **
File -> New -> Vector Asset
導(dǎo)入SVG
可以選擇Google提供的Material Icon進(jìn)行導(dǎo)入也可以選擇Local File選擇本地svg文件進(jìn)行導(dǎo)入,一般選擇后者。對(duì)文件命名后點(diǎn)擊Next ->Finish在drawable目錄下就添加了一個(gè).xml的文件
點(diǎn)擊可以進(jìn)行預(yù)覽,一看是不是很像selector、animation-list只是標(biāo)簽為vector標(biāo)簽 width、height為對(duì)應(yīng)的寬高,可以進(jìn)行設(shè)置,viewportWidth、viewportHeight這個(gè)我也不太了解大概就是視圖的寬高吧,好像作用不大,沒(méi)有設(shè)置過(guò)。path為html中的一個(gè)標(biāo)簽用來(lái)定義路徑,我們只關(guān)心path標(biāo)簽中的android:fillColor="#FBDC00"的屬性,用來(lái)改變顏色。
使用SVG
在layout新建一個(gè)activity_svg.xml文件
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_china"/>
就是這樣簡(jiǎn)單,預(yù)覽效果圖:
也可以當(dāng)背景使用
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_china">
</LinearLayout>
5.0以下版本使用SVG
上面說(shuō)了在Android5.0以上使用svg圖片是沒(méi)有任何問(wèn)題,但是怎么兼容5.0以下的機(jī)型,很多github第三方開(kāi)源庫(kù)可以解決,其實(shí)google已經(jīng)給出了解決方案,我們主要了解原生的解決辦法。
添加兼容性支持
首先,你需要在項(xiàng)目的build.gradle腳本中,增加對(duì)Vector兼容性的支持,代碼如下所示:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
```<br>
在defaultConfig中添加了<br>
vectorDrawables.useSupportLibrary = true
當(dāng)然還需要添加appcompat的支持
compile 'com.android.support:appcompat-v7:23.4.0'
**在ImageView中使用**<br>
1、我們要引用support:appcompat-v7中的view首先我們需要在XML布局文件頭部添加:<br>
xmlns:app="http://schemas.android.com/apk/res-auto"
2、 用V7下的AppCompatImageView代替ImageView<br>
3、將android:src屬性,換成app:srcCompat即可<br>
代碼如下 :<br/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_china"/>
</LinearLayout>
效果圖
<br>
這里AppCompatImageView就不做過(guò)多介紹
[官方文檔](https://developer.android.google.cn/reference/android/support/v7/widget/AppCompatImageView.html);<br>
**在background使用**<br>
根據(jù)上文是不是能推測(cè)出有app:backgroundCompat屬性呢,然而并不如我們所愿,沒(méi)有這樣的屬性。所以我們只能用 android:background這個(gè)屬性了,先不管這么多了直接4.4的機(jī)器上運(yùn)行試試,果然崩了,在這里說(shuō)明下在普通控件上使用Vector,就必須依附于StateListDrawable,InsetDrawable,LayerDrawable,LevelListDrawable,RotateDrawable我們選擇selector代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_china"/>
</selector>
這樣是不是完了呢?在運(yùn)行試試還是崩了,這里又是一個(gè)坑.....
還需要在activity中添加如下代碼:
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
完美。
-------------------
##iconfont的使用
上面介紹了把svg圖片導(dǎo)入到項(xiàng)目中,但是一個(gè)個(gè)的svg是不是很麻煩,而且drawable會(huì)有大量的文件,阿里媽媽就提供了iconfont,<br>
<font color="red">Iconfont</font>-國(guó)內(nèi)功能很強(qiáng)大且圖標(biāo)內(nèi)容很豐富的矢量圖標(biāo)庫(kù),提供矢量圖標(biāo)下載、在線存儲(chǔ)、格式轉(zhuǎn)換等功能。<br>
**iconfont的簡(jiǎn)單使用**<br>
iconfont在Android中的使用官網(wǎng)已經(jīng)做了非常詳細(xì)介紹[http://www.iconfont.cn/help/detail?helptype=code](http://www.iconfont.cn/help/detail?helptype=code)使用起來(lái)也很簡(jiǎn)單,我總結(jié)了幾步:<br>
- 首先在我的項(xiàng)目中新建一個(gè)自己的項(xiàng)目;<br>
- 從iconfont平臺(tái)選擇要使用到的圖標(biāo)或者本地導(dǎo)入svg圖片到項(xiàng)目中;<br>
- 下載代碼,把iconfont.svg和iconfont.ttf文件導(dǎo)入到項(xiàng)目中的assets文件夾中;<br>
- 用TextView代替ImagerView,找到圖標(biāo)相對(duì)應(yīng)的 HTML 實(shí)體字符碼給textView設(shè)置;<br>
- textview設(shè)置大小跟顏色,圖標(biāo)的大小顏色也會(huì)改變(這里大小最好用dp為單位,這樣不會(huì)隨著手機(jī)字體大小的改變而改變圖標(biāo)的大小);<br>
- 為Textview設(shè)置指定的ttf文字;
<TextView
android:id="@+id/text_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/red"
android:textSize="50dp"/>
//為TextView設(shè)置指定ttf文字
Typeface iconfont = Typeface.createFromAsset(getAssets(), "iconfont/iconfont.ttf");
TextView textview = (TextView)findViewById(R.id.text_icon);
textview.setTypeface(iconfont);
運(yùn)行效果圖<br>

**iconfont的封裝**<br>
每次都給TextView設(shè)置指定文字是不是也很繁瑣,而且一直不斷的在讀取iconfont.ttf文字,也很浪費(fèi)內(nèi)存,我們完全可以把這個(gè)抽離出來(lái),說(shuō)干就干。
首先我們要讀取到的是assets目錄下的iconfont.ttf文件;這里我把它放到自定義的Application中,這樣就只要讀取一次,代碼如下:
public class MyApplication extends Application {
public static Typeface iconfont;
...
public static Typeface getIconfont(Context context) {
if (iconfont != null) {
return iconfont;
} else {
iconfont = Typeface.createFromAsset(context.getAssets(), "iconfont/iconfont.ttf");
}
return iconfont;
}
這里就實(shí)例化了iconfont。然后給每TextView設(shè)置Typeface,這肯定不是我們想要的,所以我們自定義一個(gè)TextView然后初始化時(shí)setTypeface就可以了代碼如下:
public class TextViewIcon extends AppCompatTextView {
public TextViewIcon(Context context) {
super(context);
init(context);
}
public TextViewIcon(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public TextViewIcon(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
setTypeface(VcApplication.getIconfont(context));
}
}
就下了就可以直接在layout文件中使用了
<com.example.svgdemo.TextViewIcon
android:id="@+id/text_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#ff0000"
android:textSize="50dp"/>
運(yùn)行效果跟上圖一樣。<br>
**iconfont動(dòng)態(tài)設(shè)置**<br>
動(dòng)態(tài)設(shè)置通俗的說(shuō)就是在代碼里動(dòng)態(tài)的調(diào)整圖標(biāo)的大小顏色或改變圖片,iconfont改變大小顏色這很簡(jiǎn)單直接調(diào)用TextView的setTextSize和setTextColor就可以了,動(dòng)態(tài)設(shè)置圖片是不是setText呢?
textview.setText("");
運(yùn)行發(fā)現(xiàn)并不如我們所愿這里涉及到unicode 字符的問(wèn)題,
把代碼稍改一下
textview.settext("\ue643");// "&#x" 替換成 "\u",用 unicode 字符來(lái)表示
這樣問(wèn)題就解決了<br>
<br>
-------------------
##總結(jié)
通過(guò)這篇文章,我們基本就能掌握SVG在Android中的使用了,并且了解了阿里的iconfont的使用以及封裝,其實(shí)SVG在Android中的應(yīng)用還有很多列如文中提到的AnimatedVectorDrawable矢量圖動(dòng)畫(huà)等,還有我把遇到的問(wèn)題也貼出來(lái)希望大家來(lái)和我交流。怎么在Android中使用iconfont彩色圖片,以及iconfont在除TextView其他控件的使用。謝謝!!!