Android使用SVG小結


SVG的全稱是Scalable Vector Graphics,叫可縮放矢量圖形。它和位圖(Bitmap)相對,SVG不會像位圖一樣因為縮放而讓圖片質量下降。它的優點在於節約空間,使用方便。

android也在5.0中新增了對使用svg矢量圖支持,現在網上也有大把關於svg的文章但是使用時還是有遇到了許多坑,所以在這里我就總結了下我在使用svg過程中遇到的各種坑,希望對大家有所幫助。

VectorDrawable

要想在Android使用svg,首先要介紹的肯定是VectorDrawable,VectorDrawable是Android 5.0系統中引入了 VectorDrawable 來支持矢量圖(SVG),同時還引入了 AnimatedVectorDrawable 來支持矢量圖動畫。
官方文檔:
VectorDrawable,AnimatedVectorDrawable
VectorDrawable轉換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
新建一個SVGDemo項目,

新建Vector Asset文件

File -> New -> Vector Asset



導入SVG

可以選擇Google提供的Material Icon進行導入也可以選擇Local File選擇本地svg文件進行導入,一般選擇后者。對文件命名后點擊Next ->Finish在drawable目錄下就添加了一個.xml的文件
點擊可以進行預覽,一看是不是很像selector、animation-list只是標簽為vector標簽 width、height為對應的寬高,可以進行設置,viewportWidth、viewportHeight這個我也不太了解大概就是視圖的寬高吧,好像作用不大,沒有設置過。path為html中的一個標簽用來定義路徑,我們只關心path標簽中的android:fillColor=”#FBDC00”的屬性,用來改變顏色。



使用SVG

在layout新建一個activity_svg.xml文件

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/ic_china"/>

就是這樣簡單,預覽效果圖:


也可以當背景使用

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/ic_china">
</LinearLayout>

5.0以下版本使用SVG

上面說了在Android5.0以上使用svg圖片是沒有任何問題,但是怎么兼容5.0以下的機型,很多github第三方開源庫可以解決,其實google已經給出了解決方案,我們主要了解原生的解決辦法。


添加兼容性支持
首先,你需要在項目的build.gradle腳本中,增加對Vector兼容性的支持,代碼如下所示:


android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}

在defaultConfig中添加了

vectorDrawables.useSupportLibrary = true

當然還需要添加appcompat的支持

compile 'com.android.support:appcompat-v7:23.4.0'

在ImageView中使用
1、我們要引用support:appcompat-v7中的view首先我們需要在XML布局文件頭部添加:

xmlns:app="http://schemas.android.com/apk/res-auto"

2、 用V7下的AppCompatImageView代替ImageView
3、將android:src屬性,換成app:srcCompat即可
代碼如下 :

<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>

效果圖


這里AppCompatImageView就不做過多介紹
官方文檔
在background使用
根據上文是不是能推測出有app:backgroundCompat屬性呢,然而並不如我們所願,沒有這樣的屬性。所以我們只能用 android:background這個屬性了,先不管這么多了直接4.4的機器上運行試試,果然崩了,在這里說明下在普通控件上使用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>

這樣是不是完了呢?在運行試試還是崩了,這里又是一個坑…..
還需要在activity中添加如下代碼:

static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

 

完美。


iconfont的使用

上面介紹了把svg圖片導入到項目中,但是一個個的svg是不是很麻煩,而且drawable會有大量的文件,阿里媽媽就提供了iconfont,
Iconfont-國內功能很強大且圖標內容很豐富的矢量圖標庫,提供矢量圖標下載、在線存儲、格式轉換等功能。
iconfont的簡單使用
iconfont在Android中的使用官網已經做了非常詳細介紹http://www.iconfont.cn/help/detail?helptype=code使用起來也很簡單,我總結了幾步:
- 首先在我的項目中新建一個自己的項目;
- 從iconfont平台選擇要使用到的圖標或者本地導入svg圖片到項目中;
- 下載代碼,把iconfont.svg和iconfont.ttf文件導入到項目中的assets文件夾中;
- 用TextView代替ImagerView,找到圖標相對應的 HTML 實體字符碼給textView設置;
- textview設置大小跟顏色,圖標的大小顏色也會改變(這里大小最好用dp為單位,這樣不會隨着手機字體大小的改變而改變圖標的大小);
- 為Textview設置指定的ttf文字;

 <TextView
    android:id="@+id/text_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="&#xe6dd;"
    android:textColor="@color/red"
    android:textSize="50dp"/>

//為TextView設置指定ttf文字
Typeface iconfont = Typeface.createFromAsset(getAssets(), "iconfont/iconfont.ttf");
TextView textview = (TextView)findViewById(R.id.text_icon);
textview.setTypeface(iconfont);

 

運行效果圖

iconfont的封裝
每次都給TextView設置指定文字是不是也很繁瑣,而且一直不斷的在讀取iconfont.ttf文字,也很浪費內存,我們完全可以把這個抽離出來,說干就干。
首先我們要讀取到的是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;
}

 

這里就實例化了iconfont。然后給每TextView設置Typeface,這肯定不是我們想要的,所以我們自定義一個TextView然后初始化時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="&#xe643;"
    android:textColor="#ff0000"
    android:textSize="50dp"/>

 

運行效果跟上圖一樣。
iconfont動態設置
動態設置通俗的說就是在代碼里動態的調整圖標的大小顏色或改變圖片,iconfont改變大小顏色這很簡單直接調用TextView的setTextSize和setTextColor就可以了,動態設置圖片是不是setText呢?

 textview.setText("&#xe643;");

運行發現並不如我們所願這里涉及到unicode 字符的問題,
把代碼稍改一下

textview.settext("\ue643");// "&#x" 替換成 "\u",用 unicode 字符來表示

這樣問題就解決了


總結

通過這篇文章,我們基本就能掌握SVG在Android中的使用了,並且了解了阿里的iconfont的使用以及封裝,其實SVG在Android中的應用還有很多列如文中提到的AnimatedVectorDrawable矢量圖動畫等,還有我把遇到的問題也貼出來希望大家來和我交流。怎么在Android中使用iconfont彩色圖片,以及iconfont在除TextView其他控件的使用。謝謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM