Android的Paint和Canvas的使用總結
前言:
在自定義控制元件時,我們有時可能會用到Paint和Canvas這兩個類,
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:表示文字繪製的Baseline的y座標 * Paint paint:表示我們所用的畫筆 * * 注:這裡指定的y座標是Baseline的y座標, * 並不是文字的底邊的y座標,通常Baseline的y座標位於文字的中間偏下的位置 * 具體細節可檢視部落格: * */ canvas.drawText("Text",getWidth()/2,getHeight()/2,paint);
變換畫布:
rotate():表示旋轉畫布至一定的角度
/** * float degrees:表示旋轉的角度,順時針為正,逆時針為負 * float px:表示指定旋轉參考座標的x座標 * float py:表示指定旋轉參考座標的y座標 * * 注:若不指定px,py這兩個引數, * 則其預設是以控制元件的左上角作為參考座標進行旋轉的 */canvas.rotate(90,getWidth()/2,getHeight()/2);translate():表示將畫布進行一定距離的平移
/** * float dx: x方向所偏移的距離 * float dy:y方向所偏移的距離 */canvas.translate(getWidth()/2,getHeight()/2);
scale():表示將畫布進行一定比例的縮放
/** * float sx: x方向縮放的倍數 * float sy: y方向縮放的倍數 * float px: 縮放參考點的x座標 * float py: 縮放參考點的y座標 * * 注:若不指定px,py,則其預設的參考點是以左上角(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()使用示例:
/** * 在這裡,主要是體會save和restore所起的作用: * * save:表示儲存當前畫布狀態 * * restore:表示回到save時的畫布狀態, * * 這樣在save和restore之間所發生的變換畫布的操作 * 就不會影響到在執行restore之後所進行的操作, * 也就是說,此時restore恢復的畫布狀態就是save * 儲存時的畫布狀態,我們來看一下一個示例: */ /** * 示例: * 用來講述save和restore的作用 */ /** * 此時畫布的預設參考點是(0,0),通過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()時,就將當時儲存的對應某部分畫布狀態資訊恢復回來。
原始碼:
注:
關於各種繪製的效果對比,可在原始碼中自行執行檢視,
每個部分單獨取消註釋,執行即可看到對應部分的效果