Android使用SVG小結(jié)

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>
效果圖

![](http://upload-images.jianshu.io/upload_images/3693762-2023e52ff0da4d3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<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>
![](http://upload-images.jianshu.io/upload_images/3693762-e19a512562080008.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**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)并不如我們所愿![](http://upload-images.jianshu.io/upload_images/3693762-cea19976d5f0f9d2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)這里涉及到unicode 字符的問(wèn)題,
把代碼稍改一下
    
    textview.settext("\ue643");// "&#x" 替換成 "\u",用 unicode 字符來(lái)表示

這樣問(wèn)題就解決了<br>
![](http://upload-images.jianshu.io/upload_images/3693762-061cf9699bc3dd17.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<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其他控件的使用。謝謝!!!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容