前言:
上一篇已經介紹了用自己定義的屬性怎么簡單定義一個view《Android 自定義view(二) —— attr 使用》,那么接下來我們繼續深究自定義view,下一步將要去簡單理解自定義view的一個比較重要的方法 onDraw(Canvas canvas) ,在探究 onDraw方法之前,我們必須先深入了解兩個類Paint和Canvas 。
第一:認識Paint
在探究onDraw之前首先必須要認識兩個類,這里給出非常不錯的兩個資料參考網站,我也是從這里得到想要知道的東西,簡單的說這下面幾篇文章已經夠我們喝一壺了,這里我就不再獻丑了
http://www.apihome.cn/api/android/Paint.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1105/1907.html
http://blog.csdn.net/harvic880925/article/details/39080931
第二:認識Canvas
Canvas類簡單理解就是表示一塊畫布,可以在上面畫我們想畫的東西
Canvas中的方法很多,Canvas可以繪制的對象有:
- 弧線(arcs) canvas.
- 填充顏色(argb和color)
- Bitmap
- 圓(circle和oval)
- 點(point)
- 線(line)
- 矩形(Rect)
- 圖片(Picture)
- 圓角矩形 (RoundRect)
- 文本(text)
- 頂點(Vertices)
- 路徑(path)
canvas.save():把當前的繪制的圖像保存起來,讓后續的操作相當於是在一個新的圖層上的操作。
canvas.restore(); 把當前畫布返回(調整)到上一個save()狀態之前
canvas.translate(dx, dy); //把當前畫布的原點移到(dx,dy),后面的操作都以(dx,dy)作為參照點,默認原點為(0,0)
canvas.scale(x,y);擴大。x為水平方向的放大倍數,y為豎直方向的放大倍數
canvas.rotate(angel):旋轉.angle指旋轉的角度,順時針旋轉。
canvas.transform():切變。所謂切變,其實就是把圖像的頂部或底部推到一邊。
canvas.saveLayer(bounds, paint, saveFlags);
推薦文章:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html
第三:Canvas 簡單使用
有了上面對Canvas 方法的認識,那么下面我就用上面的方法來進行相關練習
/**
* Created by yishujun on 16/6/3.
*/
public class YView extends View {
private Context mContext;
//定義一個paint
private Paint mPaint;
public YView(Context context) {
this(context, null);
}
public YView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public YView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawNomal(canvas);
drawTest(canvas);
//drawDial(canvas);
}
/**
* 常規繪制 以(0,0)作為坐標原點參考點
* @param canvas
*/
private void drawNomal(Canvas canvas){
mPaint =new Paint();
// 繪制畫布背景
canvas.drawColor(Color.GRAY);
//設置畫筆顏色
mPaint.setColor(Color.BLUE);
//設置畫筆為空心 如果將這里改為Style.STROKE 這個圖中的實線圓柱體就變成了空心的圓柱體
mPaint.setStyle(Paint.Style.STROKE);
//繪制直線
canvas.drawLine(50, 50, 450, 50, mPaint);
//繪制矩形
canvas.drawRect(100, 100, 200, 300, mPaint);
//繪制矩形
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(300, 100, 400, 400, mPaint);
mPaint.setColor(Color.YELLOW);
RectF r = new RectF(150, 500, 270, 600);
// 畫矩形
canvas.drawRect(r, mPaint);
// 畫圓
canvas.drawCircle(50, 500, 50, mPaint);
RectF oval = new RectF(350, 500, 450, 700);
// 畫橢圓
canvas.drawOval(oval, mPaint);
RectF rect = new RectF(100, 700, 170, 800);
// 畫圓角矩形
canvas.drawRoundRect(rect, 30, 20, mPaint);
//繪制圓弧 繪制弧形
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
RectF re1 = new RectF(1000, 50, 1400, 200);
canvas.drawArc(re1, 10, 270, false, mPaint);
RectF re2 = new RectF(1000, 300, 1400, 500);
canvas.drawArc(re2, 10, 270, true, mPaint);
//設置Path路徑
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(3);
Path path = new Path();
path.moveTo(500, 100);
path.lineTo(920, 80);
path.lineTo(720, 200);
path.lineTo(600, 400);
path.close();
mPaint.setTextSize(46);
canvas.drawPath(path, mPaint);
canvas.drawTextOnPath("7qiuwoeruowoqjifasdkfjksjfiojio23ur8950", path, -20, -20, mPaint);
//三角形
path.moveTo(10, 330);
path.lineTo(70, 330);
path.lineTo(40, 270);
path.close();
canvas.drawPath(path, mPaint);
//把開始的點和最后的點連接在一起,構成一個封閉梯形
path.moveTo(10, 410);//繪畫基點
path.lineTo(70, 410);
path.lineTo(55, 350);
path.lineTo(25, 350);
//如果是Style.FILL的話,不設置close,也沒有區別,可是如果是STROKE模式, 如果不設置close,圖形不封閉。當然,你也可以不設置close,再添加一條線,效果一樣。
path.close();
canvas.drawPath(path, mPaint);
//參數一為漸變起初點坐標x位置,參數二為y軸位置,參數三和四分辨對應漸變終點,其中參數new int[]{startColor, midleColor,endColor}是參與漸變效果的顏色集合,
// 其中參數new float[]{0 , 0.5f, 1.0f}是定義每個顏色處於的漸變相對位置, 這個參數可以為null,如果為null表示所有的顏色按順序均勻的分布
// Shader.TileMode三種模式
// REPEAT:沿着漸變方向循環重復
// CLAMP:如果在預先定義的范圍外畫的話,就重復邊界的顏色
// MIRROR:與REPEAT一樣都是循環重復,但這個會對稱重復
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW},
null, Shader.TileMode.REPEAT);
mPaint.setShader(mShader);// 用Shader中定義定義的顏色來話
mPaint.setStyle(Paint.Style.FILL);
Path path1 = new Path();
path1.moveTo(170, 410);
path1.lineTo(230, 410);
path1.lineTo(215, 350);
path1.lineTo(185, 350);
path1.close();
canvas.drawPath(path1, mPaint);
canvas.save();
}
/**
* 繪制方法練習
* @param canvas
*/
private void drawTest(Canvas canvas){
mPaint =new Paint();
mPaint.setColor(Color.RED);
//平移測試
canvas.translate(50, 900);
canvas.drawRect(new Rect(0, 0, 100, 100), mPaint);
canvas.translate(50, 50);
canvas.drawRect(new Rect(0, 0, 100, 100), mPaint);
//縮放測試
canvas.translate(100,-50);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
// 保存畫布狀態
canvas.save();
canvas.scale(0.5f, 0.5f);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
// 畫布狀態回滾
canvas.restore();
// 先將畫布平移到矩形的中心
canvas.translate(400, -50);
canvas.drawRect(new Rect(0, 0, 300, 300), mPaint);
//旋轉測試
canvas.save();
canvas.translate(350, 50);
canvas.drawRect(new Rect(0, 0, 200, 200), mPaint);
mPaint.setColor(Color.RED);
canvas.rotate(45,200,200);
canvas.drawRect(new Rect(0, 0, 200, 200), mPaint);
canvas.restore();
//畫布錯切 三角函數tan的值
canvas.translate(350, 300);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
// y 方向上傾斜45 度
canvas.skew(0, 1);
mPaint.setColor(0x8800ff00);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
}
}