自定義View-第二步:繪制基礎(chǔ)圖形

前言

根據(jù)Gcssloop所學(xué)習(xí)的自定義View整理與筆記。

一、自定義View流程

簡化版

二、自定義View的代碼超級基礎(chǔ)框架

public class MyView extends View {
    public MyView(Context context) {
        this(context, null);
    }
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    //TODO 各種初始化內(nèi)容
    private void initView() {
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //TODO 在這里進(jìn)行繪圖操作
    }
//    @Override
//    protected void dispatchDraw(Canvas canvas) {
//        super.dispatchDraw(canvas);
//    }
}

onDraw、dispatchDraw區(qū)別

  1. onDraw()的意思是繪制視圖自身
    dispatchDraw()是繪制子視圖
  1. 無論是View還是ViewGroup對它們倆的調(diào)用順序都是onDraw()->dispatchDraw()
  2. 在繪制View控件時(shí),需要重寫onDraw()函數(shù),在繪制ViewGroup時(shí),需要重寫dispatchDraw()函數(shù)。

三、繪制流程

1.** 初始化畫筆**

//TODO 各種初始化內(nèi)容
private void initView() {
   paint = new Paint();
   paint.setColor(Color.RED);//畫筆顏色為紅色
   paint.setStyle(Paint.Style.STROKE);//畫筆模式為描邊
   paint.setStrokeWidth(5f);//畫筆寬度為5px
   paint.setAntiAlias(true); //是否使用抗鋸齒功能
}

2.繪制內(nèi)容

@Overrideprotected
 void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //TODO 在這里進(jìn)行繪圖操作
    //繪制底色
    canvas.drawColor(Color.BLACK);
    //在坐標(biāo)(200,500)的位置繪制一個(gè)點(diǎn)
    canvas.drawPoint(200, 500, paint);
    //在這些坐標(biāo)位置繪制多個(gè)點(diǎn)
    canvas.drawPoints(new float[]{
            200, 200,
            300, 300,
            400, 400
    }, paint);
    //繪制一條起點(diǎn)為(10,10),終點(diǎn)為(100,600)的直線
    canvas.drawLine(10, 10, 100, 600, paint); 
   //繪制一組線
    canvas.drawLines(new float[]{
            0, 0, 0, 400,
            0, 0, 500, 0
    }, paint);
    //繪制矩形
     //第一種方式
    canvas.drawRect(315,115,345,145,paint);
     //第二種方式
    Rect rect = new Rect(360, 115, 390, 145);
    canvas.drawRect(rect,paint);
    //第三種方式
    RectF rectF = new RectF( 335.5f, 160F,370.5f, 170.6f);
    canvas.drawRect(rectF,paint);
}
效果圖

四、 繪制一些其他形狀

  1. 圓角矩形
// 第一種
RectF rectF = new RectF(100,100,800,400);
//drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)
canvas.drawRoundRect(rectF,30,30,paint);
// 第二種,API21以上可用
canvas.drawRoundRect(100,100,800,400,30,30,paint);

** rx,ry的理解**


圓角矩形的角實(shí)際上不是一個(gè)正圓的圓弧,而是橢圓的圓弧,這里的兩個(gè)參數(shù)實(shí)際上是橢圓的兩個(gè)半徑
在rx為寬度的一半,ry為高度的一半時(shí),剛好是一個(gè)橢圓,通過上面我們分析的原理推算一下就能得到,而當(dāng)rx大于寬度的一半,ry大于高度的一半時(shí),實(shí)際上是無法計(jì)算出圓弧的,所以drawRoundRect對大于該數(shù)值的參數(shù)進(jìn)行了限制(修正),凡是大于一半的參數(shù)均按照一半來處理

  1. 橢圓
// 第一種
RectF rectF = new RectF(100,100,800,400);
canvas.drawOval(rectF,paint);
// 第二種
canvas.drawOval(100,100,800,400,paint);
橢圓原理
 // 繪制一個(gè)圓心坐標(biāo)在(500,500),半徑為400 的圓。
canvas.drawCircle(500,500,400,paint);
  1. 圓弧
// 第一種
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
 // 第二種
public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) {}

startAngle :開始角度
sweepAngle:掃過角度
useCenter:是否使用中心
demo來一個(gè)吧O(∩_∩)O~

    RectF rectF = new RectF(100, 100, 400, 300);
// 繪制背景矩形
        paint.setColor(Color.GRAY);
        canvas.drawRect(rectF, paint);
// 繪制圓弧
        paint.setColor(Color.BLUE);
        canvas.drawArc(rectF, 0, 60, false, paint);
        RectF rectF2 = new RectF(100, 400, 400, 600);
// 繪制背景矩形
        paint.setColor(Color.GRAY);
        canvas.drawRect(rectF2, paint);
// 繪制圓弧
        paint.setColor(Color.BLUE);
        canvas.drawArc(rectF2, 0, 60, true, paint);

效果圖:

五、畫個(gè)餅圖

要點(diǎn):不斷改變startAngle和sweepAngle的值就OK啦,直接舉栗子


餅圖效果圖
public class MyView extends View {
    public MyView(Context context) {
        this(context, null);
    }
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    private Paint paint;
    private int[] startAngle = new int[6];
    private int[] color = {Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA};
    //TODO 各種初始化內(nèi)容
    private void initView() {
        paint=new Paint();
        paint.setColor(Color.RED);//畫筆顏色為紅色
        paint.setStyle(Paint.Style.FILL);//畫筆模式為描邊
        paint.setStrokeWidth(5f);//畫筆寬度為5px
        paint.setAntiAlias(true); //是否使用抗鋸齒功能
        for (int i = 0; i < 5; i++) {
            startAngle[i] = i * 60 + i;
        }
        startAngle[5] = 360;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //TODO 在這里進(jìn)行繪圖操作
      //移動到屏幕(200,300)的位置,下一篇會具體講解的
        canvas.translate(200, 300);
        RectF rect = new RectF(-100, -100, 200, 200);
        for (int i = 0; i < 5; i++) {
            paint.setColor(color[i]);
            canvas.drawArc(rect, startAngle[i], startAngle[i+1]-startAngle[i], true, paint);
        }
    }}

六、canvas的各種方法

[之后會講解的,這里只提一下O(∩_∩)O~]

drawColor, drawRGB, drawARGB //使用單一顏色填充整個(gè)畫布
drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc//依次為 點(diǎn)、線、矩形、圓角矩形、橢圓、圓、圓弧
drawBitmap, drawPicture//繪制位圖和圖片
drawText, drawPosText, drawTextOnPath//依次為 繪制文字、繪制文字時(shí)指定每個(gè)文字位置、根據(jù)路徑繪制文字
drawPath//繪制路徑,繪制貝塞爾曲線時(shí)也需要用到該函數(shù)
drawVertices, drawBitmapMesh//通過對頂點(diǎn)操作可以使圖像形變,drawVertices直接對畫布作用、 drawBitmapMesh只對繪制的Bitmap作用
clipPath, clipRect//畫布剪裁,設(shè)置畫布的顯示區(qū)域
save, restore, saveLayerXxx, restoreToCount, getSaveCount//依次為 保存當(dāng)前狀態(tài)、 回滾到上一次保存的狀態(tài)、 保存圖層狀態(tài)、 回滾到指定狀態(tài)、 獲取保存次數(shù)
translate, scale, rotate, skew//畫布變換,依次為 位移、縮放、 旋轉(zhuǎn)、錯(cuò)切
getMatrix, setMatrix, concat//實(shí)際上畫布的位移,縮放等操作的都是圖像矩陣Matrix, 只不過Matrix比較難以理解和使用,故封裝了一些常用的方法。

參考網(wǎng)址

  1. Android 的Paint(畫筆)及Canvas(畫布)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容