美文网首页
Android Canvas画布解析

Android Canvas画布解析

作者: QiShare | 来源:发表于2021-12-07 10:31 被阅读0次

    1.简介

    在开发中,我们经常需要自定义View去实现各种各样的效果,在这个过程中经常需要用到Canvas画布去绘制各种各样的图形和图案,因此,熟练地掌握Canvas的各种使用方法,就显得尤为重要。本文将简要介绍Canvas的各种用法,加深大家的理解。

    2.绘制各种图形

    Canvas提供了很多绘制方法,基于这些方法,我们可以绘制出各种各样的图形,下面我们就开始介绍这些绘制方法。

    2.1 drawARGB

    此方法可以用ARGB颜色绘制一个颜色背景,方法如下:

    //a:颜色的alpha部分,取值0--255
    //r:颜色的red部分,取值0--255
    //g:颜色的green部分,取值0--255
    //b:颜色的blue部分,取值0--255
    public void drawARGB(int a, int r, int g, int b)
    

    现在使用此方法绘制一个纯色背景,示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawARGB(255,150,100,100);
    }
    

    2.2 drawArc

    先介绍其中的一个方法,方法如下:

    //left:左边到父布局左边的距离
    //top:顶边到父布局顶边的距离
    //right:右边到父布局左边的距离
    //bottom:底边到父布局顶边的距离
    //startAngle:弧开始的角度
    //sweepAngle:顺时针方向扫描的角度
    //useCenter:是否使用中心
    //paint:绘制弧的画笔,这个值不能为null
    public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)
    

    此方法用来绘制弧形,如果起始角度是负值或大于等于360,起始角度取360的模。如果扫描角度大于等于360,椭圆形将会被完全地绘制,如果扫描角度是负值,扫描角度取360的模。弧的绘制是顺时针方向,0度对应着钟表的3点钟方向。useCenter为true时的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(50,50,300,300,0,300,true,paint);
    }
    

    useCenter为false时的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(50,50,300,300,0,300,false,paint);
    }
    

    drawArc的另一个重载方法如下:

    //oval:用来定义弧形的形状和大小的椭圆的边界,这个值不能为null
    //startAngle:弧开始的角度
    //sweepAngle:顺时针方向扫描的角度
    //useCenter:是否使用中心
    //paint:绘制弧的画笔,这个值不能为null
    public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)
    

    此方法useCenter为true时的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,50,300,300);
        canvas.drawArc(rectF,0,200,true,paint);
    }
    

    此方法useCenter为false时的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,50,300,300);
        canvas.drawArc(rectF,0,200,false,paint);
    }
    

    2.3 drawBitmap

    这个方法是用来绘制位图的,这个方法有很多重载,先看其中的一个方法:

    //bitmap:要绘制的位图
    //matrix:用来变换位图的矩阵
    //paint:绘制位图的画笔,可能为null
    public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint)
    

    此方法绘制位图的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        Matrix matrix = new Matrix();
        canvas.drawBitmap(bitmap,matrix,paint);
    }
    

    看一个drawBitmap的重载方法如下:

    //bitmap:要绘制的位图
    //src:要绘制的位图的子集,即绘制的是全部或者部分位图,可能为null
    //dst:位图将要通过缩放和转换去适应的矩形
    //paint:绘制位图的画笔,可能为null
    public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
                @Nullable Paint paint)
    

    此方法用来绘制位图,通过自动缩放和转换去适应目标矩形,示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        Rect srcRect = new Rect(0,0,300,300);
        Rect dstRect = new Rect(0,0,600,600);
        canvas.drawBitmap(bitmap,srcRect,dstRect,paint);
    }
    

    再来看另外一个重载方法如下:

    //bitmap:要绘制的位图
    //src:要绘制的位图的子集,即绘制的是全部或者部分位图,可能为null
    //dst:位图将要通过缩放和转换去适应的矩形
    //paint:绘制位图的画笔,可能为null
    public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
                @Nullable Paint paint)
    

    此方法也是用来绘制通过自动缩放和转换去适应目标矩形的位图,示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        Rect srcRect = new Rect(0,0,300,300);
        RectF dstRectF = new RectF(0,0,600,600);
        canvas.drawBitmap(bitmap,srcRect,dstRectF,paint);
    }
    

    再来看绘制位图的一个方法如下:

    //bitmap:要绘制的位图
    //left:位图左边的位置
    //top:位图顶边的位置
    //paint:绘制位图的画笔,可能为null
    public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint)
    

    这个方法绘制左上角在(x,y)的位图,如果位图和画布拥有不同的密度,将会自动缩放位图,以和画布相同的密度绘制,示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        canvas.drawBitmap(bitmap,50,100,paint);
    }
    

    2.4 drawCircle

    此方法使用画笔paint绘制圆,如果半径小于等于0将不会绘制任何东西,基于画笔的样式,圆将会被填充或者绘制的是轮廓,方法如下:

    //cx:圆心的x坐标
    //cy:圆心的y坐标
    //radius:圆的半径
    //paint:绘制圆的画笔
    public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
    

    此方法的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(200,200,150,paint);
    }
    

    2.5 drawColor

    此方法使用颜色填充整个画布canvas的位图,方法如下:

    //color:绘制在画布上的颜色
    public void drawColor(@ColorInt int color)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN);
    }
    

    再来看一个重载方法如下:

    //color:绘制在画布上的颜色
    //mode:应用到颜色上的porter-duff模式
    public void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode)
    

    此方法使用颜色和porter-duff模式填充整个画布canvas的位图,示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN, PorterDuff.Mode.DARKEN);
    }
    

    2.6 drawLine

    此方法使用画笔paint和开始及终止的x,y坐标绘制线段,由于线总是轮廓式的,画笔paint的样式将会被忽略,方法如下:

    //startX:线段起始点的x坐标
    //startY:线段起始点的y坐标
    //stopX:线段结束点的x坐标
    //stopY:线段结束点的y坐标
    //paint:绘制线段的画笔
    public void drawLine(float startX, float startY, float stopX, float stopY,
                @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(50,50,300,300,paint);
    }
    

    2.7 drawLines

    此方法绘制一系列线段,每条线需要pts数组中4个连续的值。因此,绘制一条线,数组必须至少包括4个值。逻辑上和绘制下面的数组一样,先使用pts[0]、pts[1]、pts[2]、pts[3]绘制线,接着使用[4]、pts[5]、pts[6]、pts[7]绘制线,以此类推。方法如下:

    //pts:要绘制的点的数组,如[x0,y0,x1,y1,x2,y2...]
    //offset:绘制前在数组中要跳过的值的个数
    //count:在跳过偏移量后,要处理的数组中值的个数
    //paint:绘制的画笔
    public void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
                @NonNull Paint paint)
    

    此方法的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float[] pts = {50,10,100,200,300,200,200,400};
        canvas.drawLines(pts,0,8,paint);
    }
    

    再来看另一个重载方法如下:

    //pts:要绘制的点的数组,如[x0,y0,x1,y1,x2,y2...]
    //paint:绘制的画笔
    public void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float[] pts = {50,10,100,200,300,200,200,400};
        canvas.drawLines(pts,paint);
    }
    

    2.8 drawOval

    此方法使用画笔paint绘制椭圆,椭圆被填充或是轮廓由画笔paint的样式决定,方法如下:

    //left:左边到父布局左边的距离
    //top:顶边到父布局顶边的距离
    //right:右边到父布局左边的距离
    //bottom:底边到父布局顶边的距离
    //paint:绘制的画笔
    public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawOval(50,50,600,300,paint);
    }
    

    再来看一个重载方法:

    //oval:椭圆的矩形边界,这个值不能为null
    //paint:绘制的画笔,不能为null
    public void drawOval(@NonNull RectF oval, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,50,600,300);
        canvas.drawOval(rectF,paint);
    }
    

    2.9 drawPaint

    此方法使用画笔paint填充整个画布的位图,方法如下:

    //paint:在画布上绘制的画笔
    public void drawPaint(@NonNull Paint paint)
    

    2.10 drawPath

    此方法使用画笔paint绘制路径,路径被填充或是轮廓由画笔paint的样式决定,方法如下:

    //path:被绘制的路径
    //paint:绘制路径的画笔
    public void drawPath(@NonNull Path path, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Path path = new Path();
        path.moveTo(50,50);
        path.lineTo(200,100);
        path.lineTo(200,400);
        path.lineTo(150,500);
        canvas.drawPath(path,paint);
    }
    

    2.11 drawPoint

    此方法用来绘制一个点,方法如下:

    //x:点的x坐标
    //y:点的y坐标
    //paint:绘制点的画笔
    public void drawPoint(float x, float y, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPoint(100,100,paint);
    }
    

    2.12 drawPoints

    此方法绘制一系列点,每个点位于被pts[]确定的坐标的中心,点的直径由画笔的笔画宽度确定,点的形状由画笔的Cap类型确定,点的形状是正方形的,除非当Cap类型是Round的时候,点的形状是圆形的,方法如下:

    //pts:要绘制的点的数组[x0,y0,x1,y1,x2,y2...]
    //offset:绘制前跳过的值的个数
    //count:跳过偏移量之后要处理的值的个数
    //paint:绘制点的画笔
    public void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
                @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float[] pts = {50,50,100,200,300,200,200,400};
        canvas.drawPoints(pts,0,8,paint);
    }
    

    再来看另外一个重载方法如下:

    //pts:要绘制的点的数组[x0,y0,x1,y1,x2,y2...]
    //paint:绘制点的画笔
    public void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float[] pts = {50,50,100,200,300,200,200,400};
        canvas.drawPoints(pts,paint);
    }
    

    2.13 drawRGB

    此方法使用RGB颜色填充整个画布的位图,方法如下:

    //r:颜色的red部分,取值0--255
    //g:颜色的green部分,取值0--255
    //b:颜色的blue部分,取值0--255
    public void drawRGB(int r, int g, int b)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRGB(200,100,100);
    }
    

    2.14 drawRect

    此方法使用画笔绘制矩形,矩形被填充或者显示轮廓由画笔的样式确定,方法如下:

    //left:矩形的左边
    //top:矩形的顶边
    //right:矩形的右边
    //bottom:矩形的底边
    //paint:绘制矩形的画笔
    public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(50,100,500,300,paint);
    }
    

    看一个重载方法如下:

    //r:要绘制的矩形
    //paint:绘制矩形的画笔
    public void drawRect(@NonNull Rect r, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Rect rect = new Rect(50,100,500,300);
        canvas.drawRect(rect,paint);
    }
    

    再来看另外一个重载方法如下:

    //rect:要绘制的矩形
    //paint:绘制矩形的画笔
    public void drawRect(@NonNull RectF rect, @NonNull Paint paint)
    

    此方法的示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,100,500,300);
        canvas.drawRect(rectF,paint);
    }
    

    2.15 drawRoundRect

    此方法使用画笔绘制圆角矩形,矩形被填充或者显示轮廓由画笔的样式确定,方法如下:

    //rect:圆角矩形的矩形边界
    //rx:圆角的x半径
    //ry:圆角的y半径
    //paint:绘制圆角矩形的画笔
    public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,100,500,300);
        canvas.drawRoundRect(rectF,20,20,paint);
    }
    

    2.16 drawText

    此方法用来绘制文本,原点在(x,y),原点和画笔paint中的对齐设置有关,方法如下:

    //text:被绘制的文本
    //x:文本的原点的x坐标
    //y:文本基线的y坐标
    //paint:绘制文本的画笔,可以进行颜色、大小、样式等设置
    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String text = "Android Canvas";
        canvas.drawText(text,200,300,paint);
    }
    

    再看一个重载方法如下:

    //text:被绘制的文本
    //start:要绘制的文本中第一个字符的索引
    //end:(end-1)是要绘制的文本中最后一个字符的索引
    //x:文本的原点的x坐标
    //y:文本基线的y坐标
    //paint:绘制文本的画笔,可以进行颜色、大小、样式等设置
    public void drawText(@NonNull String text, int start, int end, float x, float y,
                @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String text = "Android Canvas";
        canvas.drawText(text,3,11,200,300,paint);
    }
    

    2.17 drawTextOnPath

    此方法使用画笔paint沿着路径绘制文本,画笔的对齐方式决定从何处沿着路径开始文本的绘制,方法如下:

    //text:被绘制的文本
    //path:文本应该遵循的路径
    //hOffset:沿着路径文本开始位置偏移的距离
    //hOffset:文本在路径之上或之下的偏移的距离,可以为正值或负值
    //paint:绘制文本的画笔,可以进行颜色、大小、样式等设置
    public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
                float vOffset, @NonNull Paint paint)
    

    示例如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String text = "Android Canvas";
        Path path = new Path();
        path.moveTo(50,50);
        path.lineTo(200,100);
        path.lineTo(400,400);
        canvas.drawTextOnPath(text,path,0,0,paint);
    }
    

    3.总结

    在自定义View的时候,将会经常用到Canvas,因此熟练地掌握和运用这些绘制方法就显得比较重要。使用Canvas可以绘制点、线、矩形、圆、椭圆、文本、路径、位图等各种各样的图形图案,本文详细地介绍了Canvas的各种方法,并给出了示例代码,灵活运用这些方法进行组合,就能绘制出各种各样的图案和效果。

    相关文章

      网友评论

          本文标题:Android Canvas画布解析

          本文链接:https://www.haomeiwen.com/subject/xjboxrtx.html