SVG前戲—讓你的View多姿多彩

什麼是SVG

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

svg的優點

首先簡要解釋一下矢量圖像格式和位圖圖像格式的區別。矢量圖像用點和線來描述物體,所以文件會比較小,同時也能提供高清晰的畫面,適合於直接打印或輸出。而位圖圖像的存儲單位是圖像上每一點的像素值,因此一般的圖像文件都很大,會佔用大量的網絡帶寬。SVG是一種矢量圖形格式,GIF、JPEG是光柵文件格式。有了兩者的概念後,SVG較GIF、JPEG的優勢顯而易見。

  • SVG 可被非常多的工具讀取和修改(比如記事本)
  • SVG 與 JPEG 和 GIF 圖像比起來,尺寸更小,且可壓縮性更強。
  • SVG 是可伸縮的
  • SVG 圖像可在任何的分辨率下被高質量地打印
  • SVG 可在圖像質量不下降的情況下被放大
  • SVG 圖像中的文本是可選的,同時也是可搜索的(很適合製作地圖)
  • SVG 可以與 Java 技術一起運行
  • SVG 是開放的標準
  • SVG 文件是純粹的 XML
  • svg格式相對於.jpg、.png甚至.webp可以 省時間和 省空間

推薦項目學習地址

https://github.com/geftimov/android-pathview

使用方法:

svg是在Android於5.0版本將該特性引入(Lollipop, API 21)。今天我們就討論 一下在5.0以上版本中使用方法。

1)生成svg

1、可以找美工用PS或者是AI設計成圖片後利用第三方工具進行轉化爲svg,以便我們能方便拿到svg數據

2、利用 Android Studio 具動態生成位圖,Studio內置一個名爲 Vector Asset Studio 的工具,在低版本SDK上編譯APK期間,針對VectorDrawable腳本自動生成一組PNG位圖資源BitmapDrawable,取代矢量圖形(在5.0及以後的手機上運行時會正常引用VectorDrawable)。

需要配置build.gradle:

defaultConfig {
    vectorDrawables.generatedDensities = ['hdpi','xxhdpi']
}
2)將普通SVG圖片數據轉換成Android可用數據

一般的SVG圖片數據是直接在html或jsp中可以使用,對我們android開發者來講是要 拿到svg.xml的資源的,我們可以使用NotPad++打開,查看源碼

解析SVG數據

我們知道,svg是以xml數據格式來進行描述的,既然svg本質上就是xml文件,所以從解析角度來看,能解析xml文件的工具應該幾乎都可以用來解析svg文件。

1、DOM解析
查看Android源碼可以看出,5.0引入svg後並沒有使用dom進行解析svg源文件,雖然svg號稱完全支持dom標準。筆者從dom解析的過程可以看出,Dom解析是將xml文件全部載入,組裝成一顆dom樹,然後通過節點以及節點之間的關係來解析xml文件。雖然一般情況下,svg文件是比較小的,但也不乏有些很複雜的圖片會上升到M級別,如果在解析時需要全部載入,對於Android系統來說時比較耗時的,這也許就是dom遭Android淘汰的原因之一吧。
2、SAX解析
SAX(Simple API for XML)解析器是一種基於事件的解析器,它的核心是事件處理模式,主要是圍繞着事件源以及事件處理器來工作的。當事件源產生事件後,調用事件處理器相應的處理方法,一個事件就可以得到處理。在事件源調用事件處理器中特定方法的時候,還要傳遞給事件處理器相應事件的狀態信息,這樣事件處理器才能夠根據提供的事件信息來決定自己的行爲。SAX解析器的優點是解析速度快,佔用內存少。非常適合在Android移動設備中使用
3、PUll解析
PULL解析器的運行方式和SAX類似,都是基於事件的模式。不同的是,在PULL解析過程中,我們需要自己獲取產生的事件然後做相應的操作,而不像 SAX那樣由處理器觸發一種事件的方法,執行我們的代碼。PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動設備中使 用,Android系統內部在解析各種XML時也是用PULL解析器

一般這種方式我們只有自定義View進行解析

創建View,開啓線程,進行解析,可以自己自己的需求進行繪製和加載相應的動畫

佈局中正常加載View一樣加載解析出來的svg

備註如果對於簡單的已有svg的 vectordrawable.xml,直接可以如對ImageView設置背景動畫

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:height="64dp"
  android:width="64dp"
  android:viewportHeight="600"
  android:viewportWidth="600" >
  <group
      android:name="rotationGroup"
      android:pivotX="300.0"
      android:pivotY="300.0"
      android:rotation="45.0" >
      <path
          android:name="v"
          android:fillColor="#000000"
          android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
  </group>
</vector>

 <?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vectordrawable">
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation" />
    <target
        android:name="v"
        android:animation="@animator/path_morph" />
</animated-vector>
Drawable drawable = iv.getDrawable();
if (drawable instanceof Animatable) {
            Animatable able = (Animatable) drawable;
            able.start();
}

這種方式可以幫助我們解決用原生實現起來比較麻煩的一些特殊的需求。

 多邊形

六邊形控件

使用SVG需要注意的是

一、SVG是在Android 5.0之後才支持的,所以如果想支持5.0之前的版本,最好使用兼容庫。具體使用如下:

在build.gradle的defaultConfig中添加

vectorDrawables.useSupportLibrary = true

二、繼承AppCompatActivity

Activity也需要繼承AppCompatActivity

另外:如果想在Activity代碼中動態設置SVG(VectorDrawable), 需要動態添加兼容

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

三、顯示問題

1、 UI給的SVG圖片應該顯示的是白色,但是在Android設備上顯示的確實黑色
2、 在某些手機上SVG會出現鋸齒,給用戶造成的感覺就是字體style都不一樣

一般情況下UI給我們的SVG圖片可能需要我們手動的修改一下,比如我們需要將fillColor改爲“#FFFFFFFF”這樣字體才能顯示爲白色。並且需要將width和height設置爲120dp,否則會有鋸齒

SVG的不足之處

矢量圖的優點一大把,但也不是萬能的。矢量圖特別適合icon圖標的應用場景,但是不能用於比如加載相冊時,設置的placeholder或者error這類需要頻繁切換回收的應用場景,否則會造成非常明顯的卡頓,因爲矢量圖是不被硬件加速支持的。

下期預告<<用SVG打造一個絢麗多彩的中國地圖>>

閱讀更多

近3年BAT面試真題整理合集

一招教你讀懂JVM和Dalvik之間的區別

NDK項目實戰—高仿360手機助手之卸載監聽

分享幾個Android很強勢的的開源框架

相信自己,沒有做不到的,只有想不到的

在這裏獲得的不僅僅是技術!

技術+職場

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章