Android矢量圖之VectorDrawable類(lèi)自由填充色彩
2014年6月26日的I/O 2014開(kāi)發(fā)者大會(huì)上谷歌正式推出了Android L,它帶來(lái)了全新的設(shè)計(jì)語(yǔ)言Material Design,新的API也提供了這個(gè)類(lèi)VectorDrawable 。也就是android支持SVG類(lèi)型的資源也就是矢量圖。想到矢量圖,自然就會(huì)想到位圖,何為矢量圖,何為位圖?先來(lái)說(shuō)說(shuō)位圖吧,我們經(jīng)常用的png,jpg就是位圖了,他是由一個(gè)單元一個(gè)單元的像素組成的。當(dāng)小icon遇到大屏幕手機(jī)的時(shí)候,icon如果被撐開(kāi)那就是馬賽克一樣啦。這可不是我們想要的。而矢量圖正式和它相反。矢量圖是由點(diǎn),線(xiàn),矩形,圓,弧線(xiàn)等組成的,它不會(huì)失真,而且減小文件的存儲(chǔ)空間。學(xué)會(huì)了,一些簡(jiǎn)單的icon,我們自己來(lái)畫(huà),而且更美觀(guān),符合Material Design設(shè)計(jì),何樂(lè)而不為。
概念
說(shuō)了那么多,還是來(lái)看看官網(wǎng)怎么描述的:
在xml定義<vector>標(biāo)簽畫(huà)出自己的矢量圖。
就是這樣簡(jiǎn)單的一句話(huà)。
用法
<vector> 包含很多元素來(lái)幫助我們畫(huà)出自己的矢量圖,下面,我們就來(lái)寫(xiě)兩個(gè)個(gè)例子來(lái)使用它們。這里就直接拿官網(wǎng)的例子來(lái)學(xué)習(xí)了。
1. 畫(huà)一個(gè)三角形,如下圖。
我們先來(lái)定義下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)來(lái)繪制下面的圖形。然后我們可以看到<group>標(biāo)簽,它主要是為下面path繪制的整體部分進(jìn)行一些操作,比如這里的以軸心(300,300)對(duì)它逆時(shí)針偏移45度,或者可以通過(guò)<group>標(biāo)簽name屬性來(lái)對(duì)它進(jìn)行動(dòng)畫(huà)操作等等。android:pivotX和android:pivotY指的就是軸心x,y軸。有了外面的整體結(jié)構(gòu),接下來(lái)就是通過(guò)<path> 標(biāo)簽進(jìn)行整體的繪制命令。首先是path的名字,有了這個(gè)名字我們就可以指向哪個(gè)path動(dòng)畫(huà)。android:fillColor指的是封閉圖形塊具體的顏色。然后android:pathData指的就是一些繪制命令。結(jié)合下面圖來(lái)學(xué)習(xí)繪制命令:
大寫(xiě)絕對(duì)小寫(xiě)相對(duì)參數(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í)針?lè)较颍?取順時(shí)針?lè)较?。結(jié)合下面圖來(lái)理解
這里以large-arc-flag=0,sweep-flag=0來(lái)寫(xiě)一個(gè)path看看真正效果: 代碼如下:
<path android:name="v" android:strokeColor="#000000" android:strokeWidth="2" android:pathData="A 10 10 0 0 0 100 200" />
產(chǎn)生的效果圖:
是和上面說(shuō)的一樣吧!
2. 畫(huà)一個(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>
和上面類(lèi)似,主要是android:pathData改變了。從(20.5,9.5)開(kāi)始,然后就是后面畫(huà)貝塞爾曲線(xiàn),相對(duì)起點(diǎn)水平左移1.955,垂直不移動(dòng)確定一個(gè)點(diǎn),然后相對(duì)起點(diǎn)水平左移動(dòng)-3.83,垂直往下移動(dòng)1.268確定一個(gè)點(diǎn),再相對(duì)起點(diǎn)水平左移4.5,垂直往下移動(dòng)3確定一個(gè)點(diǎn),通過(guò)這三個(gè)點(diǎn)畫(huà)貝塞爾曲線(xiàn),往下的類(lèi)似原理。
ps: 一些簡(jiǎn)單的命令我們是知道了,那么svg這么多命令,android里面這么多icon,總不能讓自己畫(huà)吧,我們?cè)趺慈W(xué)習(xí)這些命令,去畫(huà)這些icon呢。還好學(xué)習(xí)命令我們可以用android:path規(guī)則 ,畫(huà)icon的pathData數(shù)據(jù) 。這樣我們就可以畫(huà)出自己想要的數(shù)據(jù)來(lái)了。
怎么用在ImageView的背景上面呢?很簡(jiǎn)單,來(lái)看下面的代碼:
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)畫(huà)AnimatedVectorDrawable
我們還是以官網(wǎng)demo來(lái)測(cè)試。
新建一個(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,由于A(yíng)nimatedVectorDrawable在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)畫(huà)設(shè)置。指定的動(dòng)畫(huà)分別為rotation和path_morph
新建rotation和path_morph兩個(gè)動(dòng)畫(huà)放置在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)畫(huà)效果的。效果和上面三角形效果圖一樣,這里我們看下5.0以上的效果:
這樣我們就實(shí)現(xiàn)了簡(jiǎn)單的動(dòng)畫(huà)。
參考文章:如何玩轉(zhuǎn)Android矢量圖VectorDrawable
源碼下砸:VectorDrawable類(lèi)自由填充色彩
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Android軟件編程有所幫助
相關(guān)文章
Android學(xué)習(xí)筆記(二)App工程文件分析
之前寫(xiě)過(guò)一篇關(guān)于安卓環(huán)境配置以及第一個(gè)app的制作過(guò)程,下面我們來(lái)進(jìn)一步,分析下APP工程文件2014-07-07Android系統(tǒng)自帶樣式 (android:theme)
Android系統(tǒng)中自帶樣式分享,需要的朋友可以參考下2013-01-01關(guān)于A(yíng)ndroid 6.0權(quán)限的動(dòng)態(tài)適配詳解
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用戶(hù)體驗(yàn), 同時(shí)也為程序員帶來(lái)新的負(fù)擔(dān). 動(dòng)態(tài)權(quán)限管理就是這樣, 一方面讓用戶(hù)更加容易的控制自己的隱私, 一方面需要重新適配應(yīng)用權(quán)限,本文介紹了關(guān)于A(yíng)ndroid 6.0權(quán)限動(dòng)態(tài)適配的相關(guān)資料,需要的朋友可以參考下。2017-11-11解決Android Studio 3.0 butterknife:7.0.1配置的問(wèn)題
下面小編就為大家分享一篇解決Android Studio 3.0 butterknife:7.0.1配置的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android獲取驗(yàn)證碼倒計(jì)時(shí)實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android獲取驗(yàn)證碼倒計(jì)時(shí)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android實(shí)現(xiàn)將View保存成Bitmap的方法
這篇文章主要介紹了Android實(shí)現(xiàn)將View保存成Bitmap的方法,涉及Android畫(huà)布Canvas、位圖bitmap及View的相關(guān)使用技巧,需要的朋友可以參考下2016-06-06詳解Android應(yīng)用中DialogFragment的基本用法
Android App中建議使用DialogFragment作為對(duì)話(huà)框的容器,DialogFragment類(lèi)提供了創(chuàng)建對(duì)話(huà)框并管理其外觀(guān)需要的所有控件,本文主要內(nèi)容便為詳解Android應(yīng)用中DialogFragment的基本用法,而不再需要調(diào)用Dialog的方法需要的朋友可以參考下2016-05-05使用androidx BiometricPrompt實(shí)現(xiàn)指紋驗(yàn)證功能
這篇文章主要介紹了使用androidx BiometricPrompt實(shí)現(xiàn)指紋驗(yàn)證功能,對(duì)android指紋驗(yàn)證相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2021-07-07Android統(tǒng)一依賴(lài)管理的三種方式總結(jié)
為了項(xiàng)目的管理,依賴(lài)包的紡一管理是必要的,下面這篇文章主要給大家介紹了關(guān)于A(yíng)ndroid統(tǒng)一依賴(lài)管理的三種方式,文中通過(guò)實(shí)例代碼和圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01Android開(kāi)發(fā)之開(kāi)發(fā)者頭條(二)實(shí)現(xiàn)左滑菜單
本文給大家介紹Android開(kāi)發(fā)之開(kāi)發(fā)者頭條(二)實(shí)現(xiàn)左滑菜單,主要用android自帶的DrawerLayout控件實(shí)現(xiàn)的此功能,具體實(shí)現(xiàn)過(guò)程請(qǐng)參考下本文2016-04-04