1. 程式人生 > >Android的Paint和Canvas的使用總結

Android的Paint和Canvas的使用總結

前言:

在自定義控制元件時,我們有時可能會用到PaintCanvas這兩個類,

Paint相當於我們在畫畫時的畫筆,Canvs相當於我們在畫畫時的畫布,

下面來簡單講一下這兩個類常見的一些用法

Paint的使用總結:

setAlpha(int a):

設定畫筆的透明度,這樣畫筆所畫的位置就會呈一定的透明度

setAntiAlias(boolean aa):

設定 true 則表示其繪製的邊緣會做平滑處理,比如,我們一個橢圓,

那麼將這個橢圓放大之後,其邊緣就不會出現鋸齒的形狀,相對來說,

過度更自然一些。若設定為false,則放大後,可以較為清晰地看到其

邊緣會出現鋸齒的形狀。

setColor(int color):

設定畫筆顏色

setStrokeWidth(float width):

設定畫筆的大小

setStyle(Paint.Style style):

設定畫筆所畫的圖形是空心還是實心

setTextSize(float textSize):

設定畫筆所畫的字型大小

Canvas的使用總結:

繪製圖形

drawLine():表示繪製一條直線

/**
 * 畫直線
* float startX:表示直線起始座標的x座標值
* float startY:表示直線起始座標的y座標值
* float stopX: 表示直線結束座標的x座標值
* float stopY:表示直線結束座標的y座標值
* Paint paint
:表示我們所用的畫筆 */ canvas.drawLine(0,getHeight()/2,getWidth(),getHeight()/2,paint);

drawArc():表示繪製一個弧形

/**
 * 畫弧形
* float left:表示弧形呈360度顯示時,對應的最左邊那個端點所對應的 x 座標
* float top:表示弧形呈360度顯示時,對應的最上邊那個端點所對應的 y 座標* float right:表示弧形呈360度顯示時,對應的最右邊那個端點所對應的 x 座標* float bottom:表示弧形呈360度顯示時,對應的最下邊那個端點所對應的 y 座標* float startAngle
* 表示與水平方向呈多少角度開始繪製弧形,順時針的角度記為正 * float sweepAngle* 表示繪製弧形時所對應的扇形角度,數值為正,則表示從順時針方向開始繪製 * boolean useCenter* true表示扇形需要中間那一部分三角形, * false表示顯示的是:從扇形中出去中間那個三角形之後的一小部分的弧形 * Paint paint:表示我們所用的畫筆 */canvas.drawArc(200,200,500,500,0,-120,true,paint);

drawCircle():表示繪製一個圓

/**
 * float cx:表示圓心的x座標
* float cy:表示圓心的y座標
* float radius:表示圓的半徑
* Paint paint:表示我們所用的畫筆
*/
canvas.drawCircle(50,50,50,paint);

drawOval():表示繪製一個橢圓

/**
 * float left:表示橢圓最左邊那個端點所對應的x座標
* float top:表示橢圓最上邊那個端點所對應的y座標
* float right:表示橢圓最右邊那個端點所對應的x座標
* float bottom:表示橢圓最下邊那個端點所對應的y座標
* Paint paint:表示我們所用的畫筆
*/
canvas.drawOval(100,100,300,500,paint);

drawRect():表示繪製矩形
/**
 * float left:表示矩形左邊這條線所對應的 x 座標
* float top:表示矩形上邊這條線所對應的 y座標
* float right:表示矩形右邊這條線所對應的 x座標
* float bottom:表示矩形底邊這條線所對應的 y座標(單位都是px)
 * Paint paint:表示我們所用的畫筆
*/
canvas.drawRect(50,50,150,150,paint);
drawBitmap():表示繪製一張點陣圖的副本
/**
 * Bitmap bitmap:表示我們想要繪製的點陣圖是什麼樣
* float left:表示點陣圖繪製的最左邊與本身控制元件左邊的距離
* float top:表示點陣圖繪製的最上邊與本身控制元件上邊的距離
* Paint paint:表示我們所用的畫筆
*/
//這裡載圖時,省略了壓縮的過程,可自行去優化圖片的載入
//Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.raw.default_head);
//canvas.drawBitmap(bitmap,100,100,paint);
drawText():表示繪製文字
/**
 * String text:
 * float x:表示文字繪製的起始x座標
* float y:表示文字繪製的Baseliney座標
* Paint paint:表示我們所用的畫筆
*
 * 注:這裡指定的y座標是Baseliney座標,
* 並不是文字的底邊的y座標,通常Baseliney座標位於文字的中間偏下的位置
* 具體細節可檢視部落格:
*
 */
canvas.drawText("Text",getWidth()/2,getHeight()/2,paint);

變換畫布:

rotate():表示旋轉畫布至一定的角度

/**
 * float degrees:表示旋轉的角度,順時針為正,逆時針為負
* float px:表示指定旋轉參考座標的x座標
* float py:表示指定旋轉參考座標的y座標
*
 * 注:若不指定pxpy這兩個引數,
* 則其預設是以控制元件的左上角作為參考座標進行旋轉的
*/canvas.rotate(90,getWidth()/2,getHeight()/2);
translate():表示將畫布進行一定距離的平移
/**
 * float dx: x方向所偏移的距離
* float dyy方向所偏移的距離
*/canvas.translate(getWidth()/2,getHeight()/2);

scale():表示將畫布進行一定比例的縮放

/**
 * float sx: x方向縮放的倍數
* float sy: y方向縮放的倍數
* float px: 縮放參考點的x座標
* float py: 縮放參考點的y座標
*
 * 注:若不指定pxpy,則其預設的參考點是以左上角(0,0)作為參考點
*
 */canvas.scale(2,2,0,0);

skew():表示將畫布沿某個方向進行一定角度的傾斜

/**
 * 剛開始,畫布是四四方方的,
*
 * float sx:
 * 也就是說:畫布的左邊邊緣與y軸所成的角度為0
 * 當讓畫布沿 x 軸進行拉伸時,畫布的左邊邊緣就會與y軸所呈現的角度就會越來越大
* 那麼,這個角度的 tan 值就是我們第一個引數所需填寫的值
*
 * float sy:
 * 同理,畫布剛開始上邊邊緣與 x 軸所成角度為0
 * 當讓畫布沿 y 軸進行拉伸時,其上邊邊緣與x軸的角度就越來越大
* 那麼,上邊邊緣與x軸所成角度的tan值就是第二個引數所需填寫的值
*
 * 總結:
* 若之前某一點的座標是(x,y),則經過canvas.skew(sx,xy)變換之後,
* 對應變換之後的座標為(x+(sx)*y,y+(sy)*x)
 *
 */
canvas.skew(2,0);

clip....:裁剪畫布

/**
 * 剪下某一塊區域
* 在這裡以裁剪一個矩形為例
*/
canvas.clipRect(50,50,350,350);  //限制其之後繪製的有效區域只能在這一部分

儲存及恢復畫布狀態:

/**
 * 儲存畫布
* save():儲存當前畫布的狀態
* restore():返回到上一次儲存畫布狀態中去
* restoreToCount():返回到某一指定的畫布狀態中去
*
 */

save()和restore()使用示例:

/**
 * 在這裡,主要是體會saverestore所起的作用:
*
 * save:表示儲存當前畫布狀態
*
 * restore:表示回到save時的畫布狀態,
*
 * 這樣在saverestore之間所發生的變換畫布的操作
* 就不會影響到在執行restore之後所進行的操作,
* 也就是說,此時restore恢復的畫布狀態就是save
 * 儲存時的畫布狀態,我們來看一下一個示例:
*/
/**
 * 示例:
* 用來講述saverestore的作用
*/
/**
 * 此時畫布的預設參考點是(00),通過save()將其儲存下來了
*/
canvas.drawRect(new Rect(0,0,100,100), paint);
canvas.save();
/**
 * 此時畫布的參考點是(100,100* 那麼,此時繪製的矩形就處於上一個矩形的右下方的位置
*/
canvas.translate(100,100);
canvas.drawRect(new Rect(0,0,100,100), paint);
/**
 * 這次將畫布的狀態恢復到save時的畫布狀態
* 也就是參考點為(0,0*/
canvas.restore();
/**
 * 此時我們再進行繪製時,則是以(0,0)為起始參考點進行繪製,
* 我們可以通過對比透明度就可以知道其與save之前繪製的矩形重疊了
* 所以可以看出我們的推論是正確的
*/
canvas.drawRect(new Rect(0,0,100,100), paint);

restore()和restoreToCount()的區別:

/**
 * restore()restoreToCount()的區別:
* restore()* 表示恢復到上一次save時的畫布狀態
* restoreToCount()* 表示恢復到某一次save時的狀態,那麼問題來了,
* 某一次save,這個某一次怎麼確定呢?
* 細心觀察的同學可以看到:每次save()時,
* 其都是有返回值的,這個返回值,可用作restoreToCount()
 * 的引數,這樣,就可以返回指定的save狀態了
*
 * 注:
* 若是呼叫了restoreToCount()指定了某一個save* 比如在如下示例中是firstSave,那麼位於firstSave
 * 棧頂之上的畫布狀態都會被銷燬,此時若試圖通過
* restoreToCount(secondSave)去恢復到secondSave* 畫布的狀態就會報非法引數異常。
*/
/**
 * 示例:
* 通過示例向大家解釋restore()restoreToCount()的區別
*/
canvas.drawRect(new Rect(0,0,100,100), paint);
int firstSave = canvas.save();
canvas.translate(100,100);
canvas.drawRect(new Rect(0,0,100,100), paint);
int secondSave = canvas.save();
canvas.translate(100,100);//表示在原來已移動的基礎上,再進行一次移動
canvas.drawRect(new Rect(0,0,100,100), paint);
/**
 * 這裡返回的是上一次save儲存畫布時的狀態,
* 也就是secondSave時狀態,此時畫布的參考點
* 是以()作為參考點的,所以我們繪製矩形的最上角
* 座標為(100,100),這個位置的矩形是綠色的
*/
canvas.restore();
paint.setColor(GREEN);
canvas.drawRect(new Rect(0,0,100,100), paint);
/**
 * 指定返回到某一次save時的畫布狀態,
* 在這裡我們指定其為firstSave* 此時畫布的狀態就是以(0,0)作為參考點的,
* 所以之後,我們繪製矩形,就可以看到黃色的
* 矩形緊緊貼在左上角
*/
canvas.restoreToCount(firstSave);
paint.setColor(YELLOW);
canvas.drawRect(new Rect(0,0,100,100), paint);

restore()和restoreToCount()的區別:

/**
 * restore()restoreToCount()的區別:
* restore()* 表示恢復到上一次save時的畫布狀態
* restoreToCount()* 表示恢復到某一次save時的狀態,那麼問題來了,
* 某一次save,這個某一次怎麼確定呢?
* 細心觀察的同學可以看到:每次save()時,
* 其都是有返回值的,這個返回值,可用作restoreToCount()
 * 的引數,這樣,就可以返回指定的save狀態了
*
 * 注:
* 若是呼叫了restoreToCount()指定了某一個save* 比如在如下示例中是firstSave,那麼位於firstSave
 * 棧頂之上的畫布狀態都會被銷燬,此時若試圖通過
* restoreToCount(secondSave)去恢復到secondSave* 畫布的狀態就會報非法引數異常。
*/
/**
 * 示例:
* 通過示例向大家解釋restore()restoreToCount()的區別
*/
canvas.drawRect(new Rect(0,0,100,100), paint);
int firstSave = canvas.save();
canvas.translate(100,100);
canvas.drawRect(new Rect(0,0,100,100), paint);
int secondSave = canvas.save();
canvas.translate(100,100);//表示在原來已移動的基礎上,再進行一次移動
canvas.drawRect(new Rect(0,0,100,100), paint);
/**
 * 這裡返回的是上一次save儲存畫布時的狀態,
* 也就是secondSave時狀態,此時畫布的參考點
* 是以()作為參考點的,所以我們繪製矩形的最上角
* 座標為(100,100),這個位置的矩形是綠色的
*/
canvas.restore();
paint.setColor(GREEN);
canvas.drawRect(new Rect(0,0,100,100), paint);
/**
 * 指定返回到某一次save時的畫布狀態,
* 在這裡我們指定其為firstSave* 此時畫布的狀態就是以(0,0)作為參考點的,
* 所以之後,我們繪製矩形,就可以看到黃色的
* 矩形緊緊貼在左上角
*/
canvas.restoreToCount(firstSave);
paint.setColor(YELLOW);
canvas.drawRect(new Rect(0,0,100,100), paint);

saveFlag引數的作用:
表明用save()或saveLayer()儲存畫布狀態哪一部分資訊,

這樣當restore()時,就將當時儲存的對應某部分畫布狀態資訊恢復回來。

原始碼:

注:

關於各種繪製的效果對比,可在原始碼中自行執行檢視,

每個部分單獨取消註釋,執行即可看到對應部分的效果