從 0 到 1Android 自定義 View(三)畫圖的五個元素元件

兩點水發表於2017-06-11

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
Android.jpg

前言

遲來的第三篇,這篇還是知識點,不過沒有細講每個方法的運用等等,因為我個人覺得,API 方法是變的,且死記硬背效果不佳,當然能記住是好事,我們必需學會在程式設計中猜想和查詢到對應的方法,所以這裡提供的只是一些方法的概況,下一篇就是進行實踐來完善這些知識點。

目錄

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
從0到1Android自定義View(三) 畫圖的五個元素元件.png

一、畫圖五個元素元件簡介

Android Framework 提供了一些 2D 畫圖的 API,android.graphics 包就是其中之一。

通常我們在自定義 View 中需要畫一些東西,那麼基本就是需要 5 個元素元件協同來完成的。這 5 個元件分別是:

  • 顏色:Color

  • 點陣圖:Bitmap 來保持(hold)那些畫素,通過 Matrix 來使影象變換,如平移、旋轉、縮放、扭曲等

  • 畫布:Canvas 來響應畫畫(draw)的呼叫(並將其寫入 bitmap)

  • 畫筆:Paint 描述畫畫的顏色和樣式等

  • 路徑:Path 根據路徑繪製文字和剪裁畫布

其實這也很好理解,程式設計其實就是根據生活哲學創造的。比如 JAVA 的程式設計思想就是:萬事萬物皆物件。在現實生活中,我們需要畫一些東西,也是需要畫紙,畫筆,顏料等等,因此自定義 View 中,我們需要畫一些東西,也是離不開畫布(Canvas),畫筆(paint),其中我們可以調整畫布的顏色和畫筆的顏色。

下面我們一個一個類的看下相關的知識點,雖然會有點悶,可是感覺這又是必需的,過完這些知識點後,就開始一些實戰的運用了。

二、顏色:Color 類

Color 我們應該是接觸的比較多的,因此只是簡單的介紹一下使用方式。Android 系統中顏色的常用表示方法有以下 3 種:

1、int color = Color.BLUE;

2、int color = Color.argb(150,200,0,100);

3、在xml檔案中定義顏色;

三、點陣圖:Bitmap 類

1、Bitmap 類在自定義 View 中的簡介

Bitmap (android.graphics.Bitmap),是 Android 系統中的影象處理的最重要類之一。用它可以獲取影象檔案資訊,進行影象剪下、旋轉、縮放等操作,並可以指定格式儲存影象檔案。

當然,在自定義 View 中使用最多的操作大概就是一些剪下,旋轉等動畫功能了。因為 Bitmap 涉及的方面挺廣的,因為這是自定義 View 系列,主要是介紹如何通過 Matrix 在 Android 中的使影象( Bitmap )變換,如平移、旋轉、縮放、扭曲等。

2、Matrix 簡介

Matrix 內部通過維護一個 float[9] 的陣列來構成 3x3 矩陣的形式,而實際上所有的變換方法說到底就是通過更改陣列中某個或某幾個位置的數值。Matrix 提供了 setValues() 和 getValues() 方法來運算元組。

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
Matrix 矩陣格式.png

實際上我們平常利用 Matrix 來進行 Translate(平移)、Scale(縮放)、Rotate(旋轉)的操作,就是在操作著這個矩陣中元素的數值來達到我們想要的效果。但是現在問題來了,上面提到的平移、縮放、旋轉操作中,旋轉和縮放可以用乘法表示,而平移就只能用加法表示,而且 Matrix 是一個 3 X 3 的矩陣,實際上表示這些操作 2 X 2 的矩陣足矣!

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
Matrix的平移、縮放、旋轉的矩陣.png

如上,可以依次看到平移、縮放、旋轉的矩陣,其中

  • (x',y')表示執行操作後的點的座標

  • (x,y)表示執行操作前的點的座標

  • tx、ty 分別表示 x 軸、y 軸上平移的距離

  • Sx、Sy 分別表示x軸、y軸上的縮放比例

  • θ 則表示旋轉角度

其實在計算機圖形應用涉及到幾何變換,主要包括平移、旋轉、縮放。以矩陣表示式來計算這些變換時,平移是矩陣相加,旋轉和縮放則是矩陣相乘。不過,通過齊次座標(齊次座標有著廣泛的應用,包括電腦圖形及 3D 電腦視覺。使用齊次座標可讓電腦進行仿射變換,並通常,其投影變換能簡單地使用矩陣來表示。),將平移的加法合併用乘法表示。

3、Matrix 9 個元素的作用

上面都提到了 Matrix 是一個 3 X 3 的矩陣,也就是說一個 Matrix 共有 9 個元素,那麼它每個元素的值發生改變會起到什麼作用呢?

Matrix 基本變換有 4 種: 平移(translate)、縮放(scale)、旋轉(rotate) 和 錯切(skew)。這 4 種變換都是由矩陣中的 9 個元素引數控制的

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
Matrix 9 個元素的作用.png

上面提到了平移(translate)、縮放(scale)、旋轉(rotate) 和 錯切(skew) 都是由這 9 個元素控制的,當然,Android 給我們提供了一系列的方法函式,且這些變換操作,每一種操作在 Matrix 均有三類,前乘(pre),後乘(post)和設定(set)

常用API包括下面的組合形式

set pre post
translate setTranslate preTranslate postTranslate
scale setScale preScale postScale
rotate setRotate preRotate postRotate

我們用translate來講

setTranslate() 指定了移動的位置,不需要通過左乘右乘

postTranslate() 在方法內部進行的是 M' = T(dx, dy) * M,t 左乘m

preTranslate() 在方法內部進行的是 M' = M * T(dx, dy),m左乘t

post,pre的乘法計算順序是相反的,矩陣乘法不滿足交換律,所以計算結果幾乎是不同的。

可能不太好理解,不過先要知道有這回事,之後通過實踐就能很好的理解了。當然,Matrix 提供的 API 方法還有很多,羅列出來給各位看,效果也不是很好,主要是 API 方法是會變的,因此我們最重要的技能還是學會在程式設計中看 API 方法,檢視原始碼或者原始碼中的解釋介紹來看和了解相關方法的作用。

四、畫布: Canvas 類

1、Canvas 類簡介

Canvas,畫布,能夠在上面繪製各種東西,是安卓平臺 2D 圖形繪製的基礎。因為 Canvas 類是構成上層的基礎,所以它的可操作性強,裡面提供的方法也是相對基礎的,因此想弄成複雜一點的影象是有一定的難度的。

2、Canvas 類提供的 API

其實我的看法跟上面一樣,不全列出來 Canvas 類提供的 API 方法,因為太多了,列出來,相信各位也不會細看,太多的話,更不容易讓各位瞭解記憶。所以大概總結一下, 用到可以打關鍵字,就能在 AS 或者 Eclpise 中查到相關的方法了。

Canvas 提供的繪製圖形的方法,基本都是以 draw 開頭的。好,我們只要知道這個,我們只要打出關鍵字就可以知道相關的方法了,例如:

從 0 到 1Android 自定義 View(三)畫圖的五個元素元件
Canvas draw方法.png

從上面方法的名字看來我們可以知道 Canvas 可以繪製的物件有:弧線(arcs)、填充顏色(argb 和color)、 Bitmap、圓(circle 和 oval)、點(point)、線(line)、矩形(Rect)、圖片(Picture)、圓角矩形 (RoundRect)、文字(text)、頂點(Vertices)、路徑(path)。

我個人是比較不提倡死記硬背有哪些 API 方法的,通過思考,猜想 Google 的工程師可能會提供什麼方法出來,比如,上面的,Canvas 類提供了可以繪製的物件,可是隻有這些,還是不夠的,為什麼?因為我們看到的自定義 View 都是附帶一些動畫的,比如選擇等等,所以我們可以知道,Android 會提供了一些對 Canvas 位置轉換的方法:rorate、scale、translate、skew(扭曲)等。而且它允許你通過獲得它的轉換矩陣物件,也就是上面所介紹的。這些操作就像是雖然你的筆還是原來的地方畫,但是畫紙旋轉或者移動了,所以你畫的東西的方位就產生變化。為了方便一些轉換操作,Canvas 還提供了儲存和回滾屬性的方法( save 和 restore ),比如你可以先儲存目前畫紙的位置(save),然後旋轉 90 度,向下移動 100 畫素後畫一些圖形,畫完後呼叫 restore 方法返回到剛才儲存的位置。

五、畫筆: Paint 類

1、Paint 類簡介

Paint 類包含有用來畫幾何圖形、文字、點陣圖的型別和顏色等資訊,如果把 Canvas 類看作是畫板,那我們可以把 Paint類 看做是畫筆,可以根據需要畫出不同顏色和樣式的圖形、文字等內容。其實基本 Paint 類和 Canvas 類都是結合使用的。

2、Paint 類提供的 API

Paint 類提供了很多方法來設定和獲取 Paint 物件的屬性,像上面提到的觀點一樣,猜下會提供什麼 API 方法,竟然是畫筆,我們現實中有不同的顏色的畫筆,所以 API 提供了的很多方法來設定和獲取Paint 物件的屬性,像剛提到的顏色值(setColor),Alpha 值(setAlpha),字型尺寸(setTextSize)和畫筆風格,空心或者實心(setStyle)等等。當然有 set 方法肯定也會有對應的 get 方法。

六、路徑:Path 類

1、Path 類簡介

Path 類的官方定義:路徑,即無數個點連起來的線。其實也就是說 Path 類封裝了由直線和曲線構成的幾何路徑。

2、Path 類作用

上面提到的繪製都是簡單圖形(如 矩形 圓 圓弧等),而對於那些複雜一點的圖形則沒法去繪製(如繪製一個心形 正多邊形 五角星等),而使用 Path 不僅能夠繪製簡單圖形,也可以繪製這些比較複雜的圖形。另外,根據路徑繪製文字和剪裁畫布都會用到 Path。

3、Path 類提供的 API

Path 類相對來說,提供的方法不是三言兩語就能說明白的,需要通過實踐來體會,這裡只是簡單的提下,還是要通過往後實踐來加深理解的。

Path 類,上面提到可以繪製複雜的圖形,因此會有基本繪圖方法。比如繪製圓形(addCircle),繪製直線(lineTo)和繪製圓角矩形(addRoundRect)。這時我們就會想到,不是繪製複雜的圖形嗎,這些都是基本的圖形啊。那麼怎麼繪製複雜的圖形呢,當然複雜的圖形都是有基本的圖形演變來的,那麼 Path 提供了什麼特別的 API 嗎?所以 Path 提供了 lineTo,moveTo,quadTo,cubicTo 以及與之對應的 rLineTo ,rMoveTo ,rQuadTo,rCubicTo的方法。比如 lineTo(float x, float y),繪製一條 x 到 y 的直線,因為兩點決定一條直線,所以提供兩個點就行了。而 rLineTo 呢?rLineTo 方法是基於當前繪製開始點的offest。比如當前 paint 位於 (100,100) 處, rLineTo(100,100) 方法繪製出來的直線是從 (100,100) 到 (200,200) 的。也就是 rXXX 方法方便用來基於之前的繪製作連續繪製。

當然 Path 類還有一些其他的方法,比如移動畫筆到 (x,y) 處:moveTo(float x,float y),設定當前 path 的終點: setLastPoint(float x,float y) 等等一些列的方法。

相關文章