① 如何使用android的VectorDrawable類繪制矢量圖
1. 創建Vector Drawable
從相似角度來看,VectorDrawable與標准SVG圖形都是利用path值繪制完成的。不過如何利用SVG path繪制圖形並不在本篇文章的探討范圍之內,大家可以點擊此處從W3C網站處獲取必要的說明資料。在本文當中,我們只需要了解到path標簽的作用是進行圖形繪制即可。讓我們首先從SVG文件入手,看看以下圖形是如何被繪制出來的:
這一圖形共由五個主要部分所組成:
一個圓角四邊形作為CPU主體,該四邊形由兩條拱狀弧線構成。
四組各自包含五根線條的圖形,用於充當CPU的外延線路。
雖然看起來有點繁雜,但大家其實用不著糾結於以上代碼的具體含義,而且這完全不會影響到我們接下來要進行的VectorDrawable繪制工作。不過需要強調的是,我將前面提到的五大圖形組成部分在代碼中作為獨立的區塊來處理,這是為了增強代碼內容的可讀性。
首先,我們需要利用兩條拱形弧線來繪制出圓角四邊形,而在接下來的內容中我們會探討如何分別表現出上、下、左、右四個方位的外延線條。為了將上述SVG代碼轉化為VectorDrawable,大家首先需要在XML當中定義vector對象。
② 如何使用Android的VectorDrawable類繪制矢量圖
繪制矢量圖形非難事——如何使用Android的VectorDrawable類
內容概述
盡管Android系統並不能夠直接支持SVG(即可縮放矢量圖形),但Lollipop版本卻引入了一個名為VectorDrawable的新類,其允許設計人員及開發人員以純代碼方式生成類似的繪制效果。
在今天的文章中,我們將共同學習如何利用XML文件創建一個VectorDrawable,並將其以動畫方式顯示在自己的項目當中。這項功能只能在運行有Android 5.0或者更高版本的設備上實現,而且目前還不具備任何支持庫實現。本篇教程中的相關源文件可以通過GitHub網站獲取。
1. 創建Vector Drawable
從相似角度來看,VectorDrawable與標准SVG圖形都是利用path值繪制完成的。不過如何利用SVG path繪制圖形並不在本篇文章的探討范圍之內,大家可以點擊此處從W3C網站處獲取必要的說明資料。在本文當中,我們只需要了解到path標簽的作用是進行圖形繪制即可。讓我們首先從SVG文件入手,看看以下圖形是如何被繪制出來的:
這一圖形共由五個主要部分所組成:
一個圓角四邊形作為CPU主體,該四邊形由兩條拱狀弧線構成。
四組各自包含五根線條的圖形,用於充當CPU的外延線路。
以下代碼所示為如何以SVG方式繪制以上圖形:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <path id="cpu" d=" M341.087,157.478c7.417,0,13.435,6.018,13.435,13.435v170.174 c0,7.417-6.018,13.435-13.435,13.435H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913 c0-7.417,6.018-13.435,13.435-13.435H341.087z M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785 0,35.826-16.041,35.826-35.826V157.478z M193.304,408.261V462h-17.913 v-53.739H193.304z M264.957,408.261V462h-17.914v-53.739H264.957z M300.783,408.261V462h-17.914v-53.739H300.783z M229.13,408.261 V462h-17.913v-53.739H229.13z M336.609,408.261V462h-17.914v-53.739H336.609z M193.304,50v53.739h-17.913V50H193.304z M264.957,50 v53.739h-17.914V50H264.957z M300.783,50v53.739h-17.914V50H300.783z M229.13,50v53.739h-17.913V50H229.13z M336.609,50v53.739 h-17.914V50H336.609z M408.261,318.695H462v17.914h-53.739V318.695z M408.261,247.043H462v17.914h-53.739V247.043z M408.261,211.217 H462v17.913h-53.739V211.217z M408.261,282.869H462v17.914h-53.739V282.869z M408.261,175.391H462v17.913h-53.739V175.391z M50,318.695h53.739v17.914H50V318.695z M50,247.043h53.739v17.914H50V247.043z M50,211.217h53.739v17.913H50V211.217z M50,282.869 h53.739v17.914H50V282.869z M50,175.391h53.739v17.913H50V175.391z" /> </svg>
雖然看起來有點繁雜,但大家其實用不著糾結於以上代碼的具體含義,而且這完全不會影響到我們接下來要進行的VectorDrawable繪制工作。不過需要強調的是,我將前面提到的五大圖形組成部分在代碼中作為獨立的區塊來處理,這是為了增強代碼內容的可讀性。
首先,我們需要利用兩條拱形弧線來繪制出圓角四邊形,而在接下來的內容中我們會探討如何分別表現出上、下、左、右四個方位的外延線條。為了將上述SVG代碼轉化為VectorDrawable,大家首先需要在XML當中定義vector對象。以下代碼提取自本篇文章示例代碼當中的vector_drawable_cpu.xml文件。
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600" > </vector>
在此之後,大家可以向其中添加path數據。下列代碼同樣被拆分成了五個不同的path標簽而非將其作為整體處理,這當然也是為了保證內容的可讀性。
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600" > <path android:name="cpu" android:fillColor="#000000" android:pathData=" M341.087,157.478 c7.417,0,13.435,6.018,13.435,13.435 v170.174c0,7.417-6.018,13.435-13.435,13.435 H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913c0-7.417,6.018-13.435,13.435-13.435H341.087z M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785,0,35.826-16.041,35.826-35.826V157.478z" /> <path android:name="wires_bottom" android:fillColor="#000000" android:pathData=" M193.304,408.261V462h-17.913 v-53.739H193.304z M264.957,408.261V462h-17.914v-53.739H264.957z M300.783,408.261V462h-17.914v-53.739H300.783z M229.13,408.261 V462h-17.913v-53.739H229.13z M336.609,408.261V462h-17.914v-53.739H336.609z" /> <path android:name="wires_top" android:fillColor="#000000" android:pathData=" M193.304,50v53.739h-17.913V50H193.304z M264.957,50 v53.739h-17.914V50H264.957z M300.783,50v53.739h-17.914V50H300.783z M229.13,50v53.739h-17.913V50H229.13z M336.609,50v53.739 h-17.914V50H336.609z" /> <path android:name="wires_right" android:fillColor="#000000" android:pathData=" M408.261,318.695H462v17.914h-53.739V318.695z M408.261,247.043H462v17.914h-53.739V247.043z M408.261,211.217 H462v17.913h-53.739V211.217z M408.261,282.869H462v17.914h-53.739V282.869z M408.261,175.391H462v17.913h-53.739V175.391z" /> <path android:name="wires_left" android:fillColor="#000000" android:pathData=" M50,318.695h53.739v17.914H50V318.695z M50,247.043h53.739v17.914H50V247.043z M50,211.217h53.739v17.913H50V211.217z M50,282.869 h53.739v17.914H50V282.869z M50,175.391h53.739v17.913H50V175.391z" /> </vector>
正如大家所見,每個path片段都只需要利用pathData屬性進行繪制。現在我們可以將VectorDrawable XML文件作為一個可繪制對象納入到標准ImageView當中,而且其能夠根據應用程序的實際需要任意進行尺寸縮放——完全不需要再修改任何java代碼。
2. 為Vector Drawables添加動畫效果
現在我們已經了解了如何以純代碼方式創建圖形,接下來要做的是找點樂子——為其添加動畫效果。在以下動畫中,大家會發現作為延伸線路的各組線條會不斷指向並遠離CPU本體進行移動。
為了達到這一目標,大家需要將包含動畫效果的每個片段包含在一個<group>標簽當中。經過修改的vector_drawable_cpu.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="cpu_box"> <path android:name="cpu" android:fillColor="#000000" android:pathData=" M341.087,157.478 c7.417,0,13.435,6.018,13.435,13.435 v170.174c0,7.417-6.018,13.435-13.435,13.435 H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913c0-7.417,6.018-13.435,13.435-13.435H341.087z M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785,0,35.826-16.041,35.826-35.826V157.478z "/> </group> <group android:name="bottom"> <path android:name="wires_bottom" android:fillColor="#000000" android:pathData=" M193.304,408.261V462h-17.913 v-53.739H193.304z M264.957,408.261V462h-17.914v-53.739H264.957z M300.783,408.261V462h-17.914v-53.739H300.783z M229.13,408.261 V462h-17.913v-53.739H229.13z M336.609,408.261V462h-17.914v-53.739H336.609z" /> </group> <group android:name="top"> <path android:name="wires_top" android:fillColor="#000000" android:pathData=" M193.304,50v53.739h-17.913V50H193.304z M264.957,50 v53.739h-17.914V50H264.957z M300.783,50v53.739h-17.914V50H300.783z M229.13,50v53.739h-17.913V50H229.13z M336.609,50v53.739 h-17.914V50H336.609z " /> </group> <group android:name="right"> <path android:name="wires_right" android:fillColor="#000000" android:pathData=" M408.261,318.695H462v17.914h-53.739V318.695z M408.261,247.043H462v17.914h-53.739V247.043z M408.261,211.217 H462v17.913h-53.739V211.217z M408.261,282.869H462v17.914h-53.739V282.869z M408.261,175.391H462v17.913h-53.739V175.391z" /> </group> <group android:name="left"> <path android:name="wires_left" android:fillColor="#000000" android:pathData=" M50,318.695h53.739v17.914H50V318.695z M50,247.043h53.739v17.914H50V247.043z M50,211.217h53.739v17.913H50V211.217z M50,282.869 h53.739v17.914H50V282.869z M50,175.391h53.739v17.913H50V175.391z" /> </group> </vector>
接下來,我們需要為每個動畫類型創建animator文件。在本次示例中,每組線路各使用一個animator,這就意味著共需要四個animator。以下代碼所示為上方線路的動畫效果,大家還需要為下、左、右線路設定類似的效果。每個animator XML文件都被包含在了本項目的示例代碼當中。
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="translateY" android:valueType="floatType" android:valueFrom="0" android:valueTo="-10" android:repeatMode="reverse" android:repeatCount="infinite" android:ration="250" /> </set>
如大家所見,propertyName被設定為translateY,這意味著該動畫將沿Y軸方向移動。而valueFrom與valueTo則控制著位移的起點與終點。通過將repeatMode設置為reverse而repeatCount設置為infinite,整個動畫會一直循環下去,其效果則在VectorDrawable處體現出來。該動畫的ration被設定為250,其時長單位為毫秒。
為了將該動畫應用到自己的可繪制文件當中,大家需要創建一個新的animated-vector XML文件,從而將這些animator分配給各VectorDrawable組。以下代碼的作用是創建該animated_cpu.xml文件。
<?xml version="1.0" encoding="utf-8"?> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_drawable_cpu"> <target
http://mobile.51cto.com/news-478709.htm
③ Android繪圖基礎--Canvas和Drawable
Github鏈接
畫2D圖形有兩種方法:
Canvas實際上是封裝了各種draw方法的類,調用draw方法把圖形繪制到底層的Surface上,即繪制在Window上。
這個例子中構造了兩個Canvas和一個Bitmap,分別調用其draw方法,先是mCanvas往Bitmap里繪制一個方塊,再在onDraw方法內調用canvas.drawBitmap繪制這個方塊。
思考一個問題,為什麼mCanvas需要設置Bitmap?
很簡單,因為它沒有持有一塊內存地址,自然沒法繪制。來看一下draw的起點ViewRootImpl(軟體繪制,不開啟硬體加速下)。
這個通過mSurface.lockCanvas返回的Canvas是View.draw的canvas變數,所以當1,2情況時,Canvas都持有一個Bitmap,指向共享內存里的某一小塊,當調用Canvas.draw方法時就能繪制出東西。但對於自定義Canvas來說並不是,即使設置一個Bitmap和繪制了Bitmap,但不往共享內存上寫,屏幕上是不會顯示的,SurfaceView同理,通過Surface.lockCanvas獲取持有共享內存的Canvas,繪制完畢後調用Surface.unlockCanvasAndPost把繪制內容顯示到surface上並release掉Canvas。
順帶一提Canvas.save和Canvas.restore方法,如下Demo
效果圖如
畫的是三個顏色和旋轉角度都不同的小方形。
步驟1把默認坐標系旋轉20°,畫出第一個藍色的方形,步驟2保存當前的matrix(旋轉了20°),繼續旋轉20°,此時坐標系已經旋轉了40°,畫出第二個黃色的方塊,步驟3,恢復上一步保存的matrix(旋轉了20°),此時坐標系還是旋轉了20°,步驟4,再旋轉40°,此時坐標系旋轉了60°,畫出第三個黑色方塊。
Canvas.save用於保存當前matrix和clip,Canvas.restore用於恢復上次保存的matrix和clip。
Drawable是一個能畫出來的物體的抽象,使用前需要調用setBounds確定位置和大小,通過getIntrinsicHeight和getIntrinsicWidth取到實際大小。Drawable可以有幾種形式存在:Bitmap、Nine Patch、Vector、Shape、Layers等。
從Resource.getDrawable會判斷是否.xml結尾,不是的話走6,7步,如果從xml中讀取,需要getResource.getDrawable -> ResourceImpl.loadDrawableForCookie -> drawable.createFromXml -> DrawableInflater.inflateFromXmlForDensity -> drawable.inflateFromTag
看一下Shape實現類GradientDrawable的inflate實現,讀取各項屬性並賦值,到draw方法。
調用canvas.drawRect把mRect畫出來,而mRect的賦值在ensureValidRect。[圖片上傳失敗...(image-a25af0-1515826613001)]
bounds在哪裡設置的?答案是ImageView.updateDrawable內,會調用Drawable.getIntrinsicHeight賦值(從xml中size屬性讀取),再調用configureBounds -> setBounds,如果使用的不是ImageView,一定要在draw之前 調用setBounds ,否則size就會出錯。
回到loadDrawableForCookie,再看一下6,7步載入圖片的過程,通過AssetManager讀取圖片流數據,通過Drawable.createFromResourceStream這個我們經常使用的方法獲取到Drawable。
取到屏幕密度之後調用BitmapFactory.decodeResourcesStream,計算密度後調用native創建Bitmap,感興趣的同學可以看下更具體的分析文章(如 理解Bitmap )。
本文探究了兩點
Android 7.1.1 源碼
Android 官方文檔, Canvas and Drawable , Drawable 等
④ Android,想獲取這個對象裡面的Drawable應該使用那個方法
Drawable drawable=getResource().getDrawable(R.drawable.xxx);
這個例子來源於android學習手冊,360手機助手中可以下載,裡面有108個android例子,源碼文檔都可在裡面看,下面是截圖
方式一:
已將圖片保存到drawable目錄下,通過圖片id獲得Drawable或者Bitmap,此方式最常用。(若只知道圖片的名稱,還可以通過圖片的名稱獲得圖片的id)
(1)通過圖片id獲得Drawable
Drawable drawable=getResource().getDrawable(R.drawable.xxx);
(2)通過圖片id獲得Bitmap
Resource res=gerResource();
Bitmap bitmap=BitmapFactory.decodeResource(res, id);
(3)通過圖片的名稱獲得圖片的id(兩種方法)
int id =res.getIdentifier(name, defType, defPackage); //name:圖片的名,defType:資源類型(drawable,string。。。),defPackage:工程的包名
Drawable drawable=getResource().getDrawable(id);
方式二:
已將圖片保存到assest目錄下,知道圖片的名稱,通過inputstream獲得圖片Drawabl
或者 Bitmap
AssetManager asm=getAssetMg();
InputStream is=asm.open(name);//name:圖片的名稱
(1)獲得Drawable
Drawable da = Drawable.createFromStream(is, null);
(2)獲得Bitmap
Bitmap bitmap=BitmapFactory.decodeStream(is);
方式三: 圖片保存在sdcard,通過圖片的路徑h
/圖片路徑
String imgFilePath = Environment.getExternalStorageDirectory().toString()
+ 「/DCIM/device.png」;
⑤ android drawable怎麼用
try
{
XmlPullParser xp = Resources.getSystem().getXml(R.drawable.g0);
Drawable db = Drawable.createFromXml(getResources(), xp);
}
catch (XmlPullParserException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
你那個出現錯誤可能是沒有在Activity中,getResources()要在activity中才有用,嘗試Content.getResources()
⑥ android drawable importer怎麼使用
一.@代表引用資源
1.引用自定義資源。格式:@[package:]type/name
android:text="@string/hello"
2.引用系統資源。格式:@android:type/name
android:textColor="@android:color/opaque_red"
注意:其實@android:type/name是@[package:]type/name 的一個子類
二.@*代表引用系統的非public資源。格式:@*android:type/name
系統資源定義分public和非public。public的聲明在:
<sdk_path>\platforms\android-8\data\res\values\public.xml
@*android:type/name:可以調用系統定義的所有資源
@android:type/name:只能夠調用publi屬性的資源。
注意:沒在public.xml中聲明的資源是google不推薦使用的。
三.?代表引用主題屬性
另外一種資源值允許你引用當前主題中的屬性的值。這個屬性值只能在style資源和XML屬性中使用;它允許你通過將它們改變為當前主題提供的標准變化來改變UI元素的外觀,而不是提供具體的值。例如:
android:textColor="?android:textDisabledColor"
注意,這和資源引用非常類似,除了我們使用一個"?"前綴代替了"@"。當你使用這個標記時,你就提供了屬性資源的名稱,它將會在主題中被查找,所以你不需要顯示聲明這個類型(如果聲明,其形式就是?android:attr/android:textDisabledColor)。除了使用這個資源的標識符來查詢主題中的值代替原始的資源,其命名語法和"@"形式一致:?[namespace:]type/name,這里類型可選。
四.@+代表在創建或引用資源 。格式:@+type/name
含義:」+」表示在R.java中名為type的內部類中添加一條記錄。如"@+id/button"的含義是在R.java 文件中的id 這個靜態內部類添加一條常量名為button。該常量就是該資源的標識符。如果標示符(包括系統資源)已經存在則表示引用該標示符。最常用的就是在定義資源ID中,例如:
@+id/資源ID名 新建一個資源ID
@id/資源ID名 應用現有已定義的資源ID,包括系統ID
@android:id/資源ID名 引用系統ID,其等效於@id/資源ID名
android:id="@+id/selectdlg"
android:id="@android:id/text1"
android:id="@id/button3"