Android 自定義控制元件-Canvas和Paint繪圖詳解-手把手帶你繪製一個時鐘.
,Android - Paint基礎
在自定義控制元件時,經常需要使用canvas、paint等,在canvas類中,繪畫基本都是靠drawXXX()方法來完成的,在這些方法中,很多時候都需要用到paint型別的引數,
Paint作為一個非常重要的元素,功能也是非常強大的,這裡簡單列舉一些它的屬性和對應的功能.
- setAntiAlias() //設定畫筆的鋸齒效果
- setColor() //設定畫筆的顏色
- setARGB() //設定畫筆的ARGB值
- setAlpha() //設定畫筆的Alpha值
- setTextSize() //設定字型的的大小
- setStyle() //設定畫筆的風格(實心或者是空心)
- setStrokeWidth() //設定空心邊框的寬度.
-
正是由於畫筆的功能不一樣,再結合各種不同的繪圖api,這樣任意的組合就可以實現不同的繪圖效果.
例如:
mPaint = new Paint();
mPaint.setColor(getResources().getColor(R.color.colorAccent));
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth (10);
mPaint.setTextSize(100);
以上就是關於Paint類的一個簡單的介紹,更多的介紹可以參考Google的官方文件
2,Android - Canvas基礎
具體的看程式碼
canvas.drawPoint(100,100,mPaint);
//繪製一條直線
canvas.drawLine(150,150,150,300,mPaint);
float [] pts = {
300,300,300,400,
300,400,400,400,
400,400,400 ,500
};
//繪製多條直線
canvas.drawLines(pts,mPaint);
//繪製一個矩形
RectF rectF = new RectF(500,100,600,300);
canvas.drawRect(rectF,mPaint);
//繪製圓角矩形
RectF rectF2 = new RectF(700,100,900,300);
canvas.drawRoundRect(rectF2,50,50,mPaint);
//繪製一個圓
canvas.drawCircle(600,600,100,mPaint);
//繪製一個扇形
RectF rectFArc = new RectF(300,800,500,1000);
canvas.drawArc(rectFArc,0,270,true,mPaint);
mPaint.setStyle(Paint.Style.STROKE);
//繪製一個弧形
RectF rectFArc2 = new RectF(300,1100,500,1300);
canvas.drawArc(rectFArc2,0,270,false,mPaint);
//繪製橢圓 外接矩形 也就就是該橢圓為矩形的內接橢圓
RectF rectFArOval = new RectF(520,1100,720,1400);
canvas.drawOval(rectFArOval,mPaint);
//繪製文字
canvas.drawText("hello",100,100,mPaint);
Path path = new Path();
path.moveTo(100,400);
path.lineTo(200,500);
path.lineTo(100,600);
path.lineTo(50,700);
canvas.drawPath(path,mPaint);
3,簡單例項,繪製一個時鐘
先看圖
效果就如上圖所示,那這樣的效果是怎麼實現的呢?這就需要用到Canvas和Paint的相關知識了.
Canvas作為繪製圖形的直接物件,它提供了以下幾個非常有用發方法.
1. canvas.save() : 儲存畫布,它的作用是將之前的所有已經繪製的影象儲存起來,讓後續的操作就好像在一個新的圖層上,操作一樣.
2. canvas.restore() :可以理解和PhotosShop中的合併圖層操作.它的作用是我們在save之後繪製的所有影象與save之前的影象進行合併.
3. canvas.translate():畫布平移,就是將畫布的座標原點移動到你指定的位置.
4. canvas,rotate():畫布翻轉,.就是將座標系翻轉了一定的角度.
理解了以上幾個方法,那麼我們就可以開始繪製我們的時鐘了,先來分析下要繪製的這個圖形,.我們可以分成4個步驟.
- 繪製儀表盤–外面的那個大圓形
- 刻度線-
- 刻度值
- 指標
在這個例項中,第一步繪製錶盤,這個挺簡單的,只要呼叫canvas,drawCircle()來繪製一個圓盤就可以了,圓心位置和半徑按照自己的需要來確定,
程式碼如下:
mWidth = getMeasuredWidth()-100;
mHeight = getMeasuredHeight()-100;
//首先繪製一個大圓盤
Paint paintCircle = new Paint();
paintCircle.setStyle(Paint.Style.STROKE);
paintCircle.setAntiAlias(true);
paintCircle.setStrokeWidth(5);
canvas.drawCircle(mWidth/2,mHeight/2,mWidth/2,paintCircle);
第二部繪製刻度線和刻度值,我們可以將一個圓分成120根刻度線,每兩根刻度線之間的角度為3度,我們只要每繪製好一根線後,我們就畫布旋轉3度,程式碼如下:
//繪製刻度
Paint paintDegree = new Paint();
paintDegree.setStrokeWidth(3);
for (int i = 0 ;i<120 ;i++){
//大點,12點 3點 6點 9點
if (i == 0 || i == 30 || i==60 || i ==90){
paintDegree.setStrokeWidth(12);
paintDegree.setTextSize(60);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+80,paintDegree);
String degree = String.valueOf(i/10);
if (i == 0){
degree = "12";
}
canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+150,paintDegree);
}else if (i % 10 == 0){////整點
paintDegree.setStrokeWidth(9);
paintDegree.setTextSize(60);
String degree = String.valueOf(i/10);
canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+140,paintDegree);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+60,paintDegree);
}else if (i % 5 == 0){
paintDegree.setStrokeWidth(6);
paintDegree.setTextSize(20);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+40,paintDegree);
}
else{
paintDegree.setStrokeWidth(3);
paintDegree.setTextSize(20);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+20,paintDegree);
}
//每次繪製完成後將畫布旋轉3度
canvas.rotate(3, mWidth / 2, mHeight / 2);
}
最後在繪製指標:
//儲存錶盤和刻度的畫布
canvas.save();
//繪製指標
Paint paintPoint = new Paint();
Paint paintHouse = new Paint();
paintHouse.setStrokeWidth(15);
Paint paintMinute = new Paint();
paintMinute.setStrokeWidth(10);
Paint paintSecond = new Paint();
paintSecond.setStrokeWidth(8);
//將畫布的起點座標移動到圓心位置
canvas.translate(mWidth/2,mHeight/2);
canvas.drawCircle(0,0,15,paintPoint);
canvas.drawLine(0,0,0,-100,paintHouse);
canvas.drawLine(0,0,0,180,paintMinute);
canvas.drawLine(0,0,100,250,paintSecond);
//合併圖層
canvas.restore();
全部的程式碼如下:
package com.example.administrator.myscrollview.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Administrator on 2016/9/29.
*/
public class ClockView extends View {
private int mWidth,mHeight;
public ClockView(Context context) {
this(context,null);
}
public ClockView(Context context, AttributeSet attrs) {
this(context, attrs,-1);
}
public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(50,0);
mWidth = getMeasuredWidth()-100;
mHeight = getMeasuredHeight()-100;
//首先繪製一個大圓盤
Paint paintCircle = new Paint();
paintCircle.setStyle(Paint.Style.STROKE);
paintCircle.setAntiAlias(true);
paintCircle.setStrokeWidth(5);
canvas.drawCircle(mWidth/2,mHeight/2,mWidth/2,paintCircle);
//繪製刻度
Paint paintDegree = new Paint();
paintDegree.setStrokeWidth(3);
for (int i = 0 ;i<120 ;i++){
//大點,12點 3點 6點 9點
if (i == 0 || i == 30 || i==60 || i ==90){
paintDegree.setStrokeWidth(12);
paintDegree.setTextSize(60);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+80,paintDegree);
String degree = String.valueOf(i/10);
if (i == 0){
degree = "12";
}
canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+150,paintDegree);
}else if (i % 10 == 0){////整點
paintDegree.setStrokeWidth(9);
paintDegree.setTextSize(60);
String degree = String.valueOf(i/10);
canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+140,paintDegree);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+60,paintDegree);
}else if (i % 5 == 0){
paintDegree.setStrokeWidth(6);
paintDegree.setTextSize(20);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+40,paintDegree);
}
else{
paintDegree.setStrokeWidth(3);
paintDegree.setTextSize(20);
canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+20,paintDegree);
}
//每次繪製完成後將畫布旋轉3度
canvas.rotate(3, mWidth / 2, mHeight / 2);
}
//儲存錶盤和刻度的畫布
canvas.save();
//繪製指標
Paint paintPoint = new Paint();
Paint paintHouse = new Paint();
paintHouse.setStrokeWidth(15);
Paint paintMinute = new Paint();
paintMinute.setStrokeWidth(10);
Paint paintSecond = new Paint();
paintSecond.setStrokeWidth(8);
//將畫布的起點座標移動到圓心位置
canvas.translate(mWidth/2,mHeight/2);
canvas.drawCircle(0,0,15,paintPoint);
canvas.drawLine(0,0,0,-100,paintHouse);
canvas.drawLine(0,0,0,180,paintMinute);
canvas.drawLine(0,0,100,250,paintSecond);
//合併圖層
canvas.restore();
}
}
效果
到這,本文就結束了,希望對大家有所幫助,謝謝.