標籤:
安卓5.0Lollipop發布以來VectorDrawable作為安卓環境下的向量化圖形的方式一直由於相容性問題而很少被用到,由於只能用於5.0以上系統,導致現在多少安卓機無法使用而一直被開發人員無限擱置。在官方給出相容性的解決方案之前,開發人員社區已經有幾個解決方案了。比如:
https://github.com/trello/victor
https://github.com/telly/MrVector
https://github.com/wnafee/vector-compat
但是就效果和易用性而言,我個人並不看好,其中MrVector已經停止維護,而vector-compat也已經很長時間沒有更新過,而且經博主測試發現僅適用於Android gradle plugin 1.4以下的版本,1.5以後存在無法正確編譯的問題。
官方也一直沒有給出一個 VectorDrawableCompat 支援庫來解決相容性問題。
Android gradle plugin 1.5發布以後,加入了一個跟VectorDrawable有關的新功能。Android build tools 提供了另外一種解決相容性的方案,如果編譯的版本是5.0之前的版本,那麼build tools 會把VectorDrawable產生對應的png圖片,這樣在5.0以下的版本則使用的是產生的png圖,而在5.0以上的版本中則使用VectorDrawable
在build.gradle添加generatedDensities配置,可以配置產生的png圖片的密度:
defaultConfig { applicationId "com.liaoinstan.vectordrawablesupport" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" generatedDensities = [‘hdpi‘, ‘xhdpi‘] }
不配置,預設全部產生。
那麼,接下來測試一下:
建立一個支援5.0以下版本的工程,我這裡最低支援到15,不配置generatedDensities 預設全部產生
defaultConfig { applicationId "com.liaoinstan.vectordrawablesupport" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" }
在drawable下建立一個vector.xml配置一張向量圖:
<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android" android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <group android:name="android"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298" /> <path android:name="left_eye" android:fillColor="#FFFFFF" android:pathData="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438" /> <path android:name="right_eye" android:fillColor="#FFFFFF" android:pathData="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438" /> <path android:name="left_arm" android:fillColor="#9FBF3B" android:pathData="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z" /> <path android:name="body" android:fillColor="#9FBF3B" android:pathData="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489H140.396z" /> <path android:name="right_arm" android:fillColor="#9FBF3B" android:pathData="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z" /> </group></vector>
然後在布局中添加一個ImageView引用該向量圖:
<ImageView android:id="@+id/imageView" android:layout_width="300dp" android:layout_height="300dp" android:src="@drawable/vector" />
效果如下:
然後打包編譯,從工程目錄下找到編譯產生的apk檔案,路徑如下:
VectorDrawableSupport\app\build\outputs\apk
然後將apk使用解壓軟體解壓,在res檔案夾下可以找到產生的各個螢幕密度對應的資源檔:
裡面分別為不同解析度的螢幕產生了不同規格的png圖片
這種方案缺失解決了目前存在的VectorDrawable 的向下相容的問題,但是為VectorDrawable 提供了各種複雜動畫效果的AnimatedVectorDrawable依然無法在5.0以下的機型使用。
目前也沒有什麼較好的解決方案,一般通過機型的適配來為不同安卓版本製作2種資源,一種是支援動畫的給5.0以上機器使用,一種是不支援動畫的給5.0以下的機型使用。在使用AnimatedVectorDrawable的時候,把 AnimatedVectorDrawable資源放到 drawable-v21 目錄中,並且在 drawable 中提供一個和 AnimatedVectorDrawable 同名字的資源來在 5.0之前的版本使用,在這個 xml 檔案中可以使用一個 selector 來替代這個動畫。
注意有時候為了簡潔可能會把VectorDrawable下的pathData放到string.xml中,然後在VectorDrawable下引用,如:
<path android:name="right_arm" android:fillColor="#9FBF3B" android:pathData="@string/mypath" />
如果通過產生png來相容5.0以下機型的話,會報pathData錯誤,編譯器不會去讀取string.xml,我也不知道為啥要這樣限制,總之只能把pathData寫到VectorDrawable下。
<path android:name="head" android:fillColor="#9FBF3B" android:pathData="M 12, 4 L 10.59, 13 L 18.99, 13 L 12, 20z" />
AnimatedVectorDrawable確實是一個非常實用的工具,能夠通過配置來實現各種複雜的動畫效果,讓人眼前一亮,但是目前的相容性問題卻很讓人頭疼,改天再寫寫AnimatedVectorDrawable吧。
android開發遊記:VectorDrawable向量圖相容性問題的解決方案