Android矢量圖之VectorDrawable類自由填充色彩
2014年6月26日的I/O 2014開發(fā)者大會(huì)上谷歌正式推出了Android L,它帶來了全新的設(shè)計(jì)語言Material Design,新的API也提供了這個(gè)類VectorDrawable 。也就是android支持SVG類型的資源也就是矢量圖。想到矢量圖,自然就會(huì)想到位圖,何為矢量圖,何為位圖?先來說說位圖吧,我們經(jīng)常用的png,jpg就是位圖了,他是由一個(gè)單元一個(gè)單元的像素組成的。當(dāng)小icon遇到大屏幕手機(jī)的時(shí)候,icon如果被撐開那就是馬賽克一樣啦。這可不是我們想要的。而矢量圖正式和它相反。矢量圖是由點(diǎn),線,矩形,圓,弧線等組成的,它不會(huì)失真,而且減小文件的存儲(chǔ)空間。學(xué)會(huì)了,一些簡單的icon,我們自己來畫,而且更美觀,符合Material Design設(shè)計(jì),何樂而不為。
概念
說了那么多,還是來看看官網(wǎng)怎么描述的:
在xml定義<vector>標(biāo)簽畫出自己的矢量圖。
就是這樣簡單的一句話。
用法
<vector> 包含很多元素來幫助我們畫出自己的矢量圖,下面,我們就來寫兩個(gè)個(gè)例子來使用它們。這里就直接拿官網(wǎng)的例子來學(xué)習(xí)了。
1. 畫一個(gè)三角形,如下圖。

我們先來定義下vectordrawable.xml :
<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>
基本結(jié)構(gòu)就是這樣,我們可以看到他有兩個(gè)寬高度描述, android:height和android:height支持所有的尺寸單元,一般我們用dp,它指的是矢量圖的寬高大小。android:viewportWidth和 android:viewportHeight可以理解為在64dp里面取600個(gè)點(diǎn)做為坐標(biāo)來繪制下面的圖形。然后我們可以看到<group>標(biāo)簽,它主要是為下面path繪制的整體部分進(jìn)行一些操作,比如這里的以軸心(300,300)對它逆時(shí)針偏移45度,或者可以通過<group>標(biāo)簽name屬性來對它進(jìn)行動(dòng)畫操作等等。android:pivotX和android:pivotY指的就是軸心x,y軸。有了外面的整體結(jié)構(gòu),接下來就是通過<path> 標(biāo)簽進(jìn)行整體的繪制命令。首先是path的名字,有了這個(gè)名字我們就可以指向哪個(gè)path動(dòng)畫。android:fillColor指的是封閉圖形塊具體的顏色。然后android:pathData指的就是一些繪制命令。結(jié)合下面圖來學(xué)習(xí)繪制命令:

大寫絕對小寫相對參數(shù)加逗號(hào),和canvas繪制差不多。解釋下最后一個(gè)A, rx和ry指的是以(x,y)為軸心的x軸和y軸的半徑,x-rotation指的是x軸旋轉(zhuǎn)角度,large-arc-flag 為0時(shí)表示取小弧度,1時(shí)取大弧度,sweep-flag 0取逆時(shí)針方向,1取順時(shí)針方向 。結(jié)合下面圖來理解

這里以large-arc-flag=0,sweep-flag=0來寫一個(gè)path看看真正效果: 代碼如下:
<path
android:name="v"
android:strokeColor="#000000"
android:strokeWidth="2"
android:pathData="A 10 10 0 0 0 100 200"
/>
產(chǎn)生的效果圖:

是和上面說的一樣吧!
2. 畫一個(gè)心型,如下圖。

代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="256dp"
android:width="256dp"
android:viewportWidth="32"
android:viewportHeight="32">
<!-- draw a path -->
<path android:fillColor="#8fff"
android:pathData="M20.5,9.5
c-1.955,0,-3.83,1.268,-4.5,3
c-0.67,-1.732,-2.547,-3,-4.5,-3
C8.957,9.5,7,11.432,7,14
c0,3.53,3.793,6.257,9,11.5
c5.207,-5.242,9,-7.97,9,-11.5
C25,11.432,23.043,9.5,20.5,9.5z" />
</vector>
和上面類似,主要是android:pathData改變了。從(20.5,9.5)開始,然后就是后面畫貝塞爾曲線,相對起點(diǎn)水平左移1.955,垂直不移動(dòng)確定一個(gè)點(diǎn),然后相對起點(diǎn)水平左移動(dòng)-3.83,垂直往下移動(dòng)1.268確定一個(gè)點(diǎn),再相對起點(diǎn)水平左移4.5,垂直往下移動(dòng)3確定一個(gè)點(diǎn),通過這三個(gè)點(diǎn)畫貝塞爾曲線,往下的類似原理。
ps: 一些簡單的命令我們是知道了,那么svg這么多命令,android里面這么多icon,總不能讓自己畫吧,我們怎么去學(xué)習(xí)這些命令,去畫這些icon呢。還好學(xué)習(xí)命令我們可以用android:path規(guī)則 ,畫icon的pathData數(shù)據(jù) 。這樣我們就可以畫出自己想要的數(shù)據(jù)來了。
怎么用在ImageView的背景上面呢?很簡單,來看下面的代碼:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/vectordrawable" />
</LinearLayout>
這樣效果是不是可以看到了呢,運(yùn)行下,效果如上面心型,然后試著去改下他的大小,其實(shí)他不會(huì)變形的。
矢量圖動(dòng)畫AnimatedVectorDrawable
我們還是以官網(wǎng)demo來測試。
新建一個(gè)xml文件vector_drawable.xml,放在drawable里面,代碼如下:
<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>
然后新建一個(gè)xml文件vector_drawable_anim.xml,由于AnimatedVectorDrawable在support:appcompat-v7:23.3兼容到android L(5.0)以上。所以我們放置在drawable-v21文件夾下,代碼如下:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_drawable" >
<target
android:name="rotationGroup"
android:animation="@anim/rotation" />
<target
android:name="v"
android:animation="@anim/path_morph" />
</animated-vector>
這里我們需要指定一個(gè)android:drawable,指向vector_drawable_anim.xml文件,然后根據(jù)group的name或者path的name進(jìn)行動(dòng)畫設(shè)置。指定的動(dòng)畫分別為rotation和path_morph
新建rotation和path_morph兩個(gè)動(dòng)畫放置在anim文件夾下,代碼如下:
rotation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="6000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
</set>
path_morph.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="3000"
android:propertyName="pathData"
android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
android:valueType="pathType"/>
</set>
然后是5.0以下activity_main.xml,放置在layout下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/image_view"
android:layout_width="400dp"
android:layout_height="400dp"
app:srcCompat="@drawable/vector_drawable"/>
</LinearLayout>
然后是5.0以上activity_main.xml,放置在layout-v21文件夾下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/image_view"
android:layout_width="400dp"
android:layout_height="400dp"
app:srcCompat="@drawable/vector_drawable_anim" />
</LinearLayout>
最后MainActivity添加代碼:
ImageView imageView = (ImageView) findViewById(R.id.image_view);
Drawable drawable = imageView.getDrawable();
//AnimatedVectorDrawableCompat實(shí)現(xiàn)了Animatable接口
if (drawable instanceof Animatable){
((Animatable) drawable).start();
}
然后我們運(yùn)行在5.0以下是不帶動(dòng)畫效果的。效果和上面三角形效果圖一樣,這里我們看下5.0以上的效果:

這樣我們就實(shí)現(xiàn)了簡單的動(dòng)畫。
參考文章:如何玩轉(zhuǎn)Android矢量圖VectorDrawable
以上就是本文的全部內(nèi)容,希望對大家學(xué)習(xí)Android軟件編程有所幫助
相關(guān)文章
OpenGL Shader實(shí)例分析(7)雪花飄落效果
這篇文章主要為大家詳細(xì)介紹了OpenGL Shader實(shí)例分析第7篇,實(shí)現(xiàn)雪花飄落效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
Android開發(fā)之Android.mk模板的實(shí)例詳解
這篇文章主要介紹了Android開發(fā)之Android.mk模板的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
詳解Android使用Socket對大文件進(jìn)行加密傳輸
這篇文章主要介紹了詳解Android使用Socket對大文件進(jìn)行加密傳輸,使用Socket進(jìn)行文件傳輸過程時(shí),需要先進(jìn)行加密,有興趣的可以了解一下。2017-01-01
Android 中SwipeRefreshLayout與ViewPager滑動(dòng)事件沖突解決方法
這篇文章主要介紹了Android 中SwipeRefreshLayout與ViewPager滑動(dòng)事件沖突解決方法的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android Studio使用ButterKnife和Zelezny的方法
這篇文章主要為大家詳細(xì)介紹了Android Studio使用ButterKnife和Zelezny的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Android自定義ImageView實(shí)現(xiàn)在圖片上添加圖層效果
這篇文章給大家主要介紹了利用Android自定義ImageView如何實(shí)現(xiàn)在圖片上添加圖層的效果,實(shí)現(xiàn)的效果類似在圖片增加秒殺、搶光等標(biāo)簽圖片,對大家開發(fā)的時(shí)候具有一定的參考借鑒價(jià)值,有需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。2016-11-11
詳細(xì)分析Android中onTouch事件傳遞機(jī)制
相信不少朋友在剛開始學(xué)習(xí)Android的時(shí)候,對于onTouch相關(guān)的事件一頭霧水。分不清onTouch(),onTouchEvent()和OnClick()之間的關(guān)系和先后順序,所以覺得有必要搞清onTouch事件傳遞的原理。經(jīng)過一段時(shí)間的琢磨以及相關(guān)博客的介紹,這篇文章就給大家詳細(xì)的分析介紹下。2016-10-10
android studio logcat 無篩選 顯示全部日志 無應(yīng)用包名區(qū)分方式
這篇文章主要介紹了android studio logcat 無篩選 顯示全部日志 無應(yīng)用包名區(qū)分方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Android編程實(shí)現(xiàn)獲得內(nèi)存剩余大小與總大小的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)獲得內(nèi)存剩余大小與總大小的方法,涉及Android基于ActivityManager實(shí)現(xiàn)內(nèi)存信息的操作技巧,需要的朋友可以參考下2015-12-12

