• Android Canvas的使用


    前言

    android.graphics.Canvas 一般在自定义View中,重写 onDraw(Canvas canvas) 方法时用到。

    	/**
         * Implement this to do your drawing.
         *
         * @param canvas the canvas on which the background will be drawn
         */
        @Override
        protected void onDraw(Canvas canvas) {
        	super.onDraw(canvas);
    		
    		canvas.xxx // 自己的逻辑
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Paint 的使用

    Paint 叫画笔,它决定了颜色、画笔宽度、填充效果等。
    Canvas 是搭配 Paint 使用的,使用 Canvas 要先初始化 Paint 。如,

    Paint paintPointRed = new Paint();
    
    paintPointRed.setColor(Color.RED); // 设置画笔颜色
    paintPointRed.setFlags(Paint.ANTI_ALIAS_FLAG); // 设置抗锯齿
    paintPointRed.setStrokeWidth(5f); //设置画笔宽度
    paintPointRed.setStyle(Paint.Style.STROKE);// 设置只描边,还有填充、填充且描边可选,默认填充
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    绘制颜色

    Canvas.drawColor(int color) :绘制颜色,参数传具体的颜色值就行。

    canvas.drawColor(Color.LTGRAY); 效果就是 View 显示灰色,
    在这里插入图片描述

    绘制点

    Canvas.drawPoint(float x, float y, Paint paint) :在坐标(x,y) 处绘制一个点。

    Canvas.drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) :根据数组 pts 绘制多个点。

    根据传入的单个坐标或者坐标数组画点,

    private Paint paintPointRed = new Paint();
    private Paint paintPointGreen = new Paint();
    
    paintPointRed.setColor(Color.RED);
    paintPointRed.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintPointRed.setStrokeWidth(5f);
    
    paintPointGreen.setColor(Color.GREEN);
    paintPointGreen.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintPointGreen.setStrokeWidth(20f);
    
    canvas.drawPoint(100,50, paintPointRed);
    	
    canvas.drawPoints(new float[]{
                    200,80,
                    220,60,
                    240,40,
            },paintPointRed);
    
    canvas.drawPoints(new float[]{
                    200,200,
                    300,300,
                    400,400,
                    500,500,
                    600,600,
            },paintPointGreen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    我用的两种画笔,画笔颜色不同、宽度不同,效果对比,
    在这里插入图片描述
    从例子中可以看出,画布坐标原点(0,0) 是显示区域左上角 。

    画布坐标

    默认情况下,坐标原点(0,0) 是显示区域左上角。

    使用 Canvas.translate(float dx, float dy) 可以修改画布的坐标原点,

    例,先画了点,修改画布坐标原点后,再画同样的点,

    		canvas.drawPoint(100,50, paintPointRed);
            canvas.drawPoints(new float[]{
                    200,80,
                    220,60,
                    240,40,
            },paintPointRed);
    
            canvas.drawPoints(new float[]{
                    200,200,
                    300,300,
                    400,400,
                    500,500,
                    600,600,
            },paintPointGreen);
    
            canvas.translate(800,0);  //修改画布坐标原点
            canvas.drawPoint(100,50, paintPointRed);
            canvas.drawPoints(new float[]{
                    200,80,
                    220,60,
                    240,40,
            },paintPointRed);
    
            canvas.drawPoints(new float[]{
                    200,200,
                    300,300,
                    400,400,
                    500,500,
                    600,600,
            },paintPointGreen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    效果如图,说明画布坐标原点已经变更了。画布坐标原点不同,显示效果不同,so ,变更画布坐标原点有风险,修改需谨慎。
    在这里插入图片描述
    修改画布坐标原点前后,坐标轴是这样的,
    在这里插入图片描述

    绘制直线

    Canvas.drawLine(float startX, float startY, float stopX, float stopY,NonNull Paint paint) :通过两个点 (startX, startY) 、(stopX, stopY) 确定一条直线。

    画笔决定线条的颜色、宽度等。

    private Paint paintLine1 = new Paint();
    private Paint paintLine2 = new Paint();
    
    paintLine1.setColor(Color.RED);
    paintLine1.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintLine2.setColor(Color.YELLOW);
    paintLine2.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintLine2.setStrokeWidth(20f);
    
    canvas.drawLine(100,100, 500,100, paintLine1);
    canvas.drawLine(100,200, 500,400, paintLine1);
    canvas.drawLine(100,500, 200,600, paintLine2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    效果,
    在这里插入图片描述

    绘制曲线

    Canvas.drawPath(@NonNull Path path, @NonNull Paint paint) :通过 Path 构建贝塞尔曲线,依据 path 画出曲线。

    private Paint paintLinePath = new Paint();
    paintLinePath.setColor(Color.MAGENTA);
    paintLinePath.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintLinePath.setStrokeWidth(5f);
    
    Path path = new Path();
    path.moveTo(200,200);
    path.cubicTo(200,700,800,700, 1000,300);
    canvas.drawPath(path, paintLinePath);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    效果,
    在这里插入图片描述
    不对啊,说是画线,怎么出来个图像,按理应该只有下面弧形才对。

    不着急,这和画笔的 Style 有关,默认是填充效果 Paint.Style.FILL ,修改为描边效果 Paint.Style.STROKE

    paintLinePath.setStyle(Paint.Style.FILL);
    
    • 1

    效果如图,nice
    在这里插入图片描述

    绘制文字

    drawText(String text, float x, float y, Paint paint) :在坐标 (x,y) 处绘制文本。

    drawText(String text, int start, int end, float x, float y,Paint paint) :在坐标 (x,y) 处绘制文本,文本只显示第 start 到第 end-1 位 。

    canvas.drawText("CanvasActivity", 100 , 300, paintText);
    canvas.drawText("CanvasActivity", 2,9,100 , 350, paintText);
    
    • 1
    • 2

    效果,
    在这里插入图片描述

    绘制圆形

    Canvas.drawCircle(float cx, float cy, float radius, Paint paint) :以坐标 (cx,cy) 为圆心绘制半径为 radius 的圆形。

    private Paint paintCircleMagenta = new Paint();
    private Paint paintCircleGreen = new Paint();
    
    paintCircleMagenta.setColor(Color.MAGENTA);
    paintCircleMagenta.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintCircleGreen.setColor(Color.GREEN);
    paintCircleGreen.setFlags(Paint.ANTI_ALIAS_FLAG);
    
    canvas.drawCircle(100,100,50, paintCircleMagenta);
    
    canvas.drawCircle(400,300,100, paintCircleGreen);
    
    canvas.drawCircle(700,300,100, paintCircleGreen);
    canvas.drawCircle(700,300,50, paintCircleMagenta);
    
    canvas.drawCircle(1000,300,50, paintCircleMagenta);
    canvas.drawCircle(1000,300,100, paintCircleGreen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    效果,
    在这里插入图片描述

    说明后面绘制的图像会覆盖前面绘制的。

    绘制椭圆

    Canvas.drawOval(RectF oval, Paint paint) :通过 RectF 确定椭圆位置并绘制。
    RectF(float left, float top, float right, float bottom) : 初始化 RectF 时根据坐标 (left,top)、(right,bottom) 确定矩形的左上角、右下角,得到最大内切椭圆。

    Canvas.drawOval(float left, float top, float right, float bottom, Paint paint) :通过坐标确定椭圆位置并绘制。

    个人理解,根据坐标得到矩形,矩形确定最大内切椭圆。

    private Paint paintOval1 = new Paint();
    paintOval1.setColor(Color.BLUE);
    paintOval1.setFlags(Paint.ANTI_ALIAS_FLAG);
    
    canvas.drawOval(new RectF(100,100,300,300), paintOval1);
    canvas.drawOval(new RectF(400,100,800,300), paintOval1);
    
    paintOval1.setStyle(Paint.Style.STROKE);//只描边
    paintOval1.setStrokeWidth(5f);
    canvas.drawOval(900,100,1100,600, paintOval1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    效果,
    在这里插入图片描述

    绘制弧形

    Canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) :通过 RectF 确定弧形位置并绘制。
    Canvas.drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, Paint paint) :通过坐标确定弧形位置并绘制 。

    个人理解,根据坐标得到矩形,矩形确定最大内切椭圆,根据参数来截取椭圆区域得到弧形。

    private Paint paintArc1 = new Paint();
    paintArc1.setColor(Color.CYAN);
    paintArc1.setFlags(Paint.ANTI_ALIAS_FLAG);
            
    canvas.drawRect(100,100 ,400,300,paintRect3); // 同位置绘制矩形
    canvas.drawArc(100,100,400,300,0,90,false,paintArc1);
    
    canvas.drawRect(100,500 ,400,700,paintRect3);// 同位置绘制矩形
    canvas.drawArc(new RectF(100,500,400,700),270,-90,true,paintArc1);
    
    
    canvas.drawRect(500,100 ,900,500,paintRect3);// 同位置绘制矩形
    canvas.drawArc(new RectF(500,100 ,900,500),270,-360,true,paintArc1);//以绘制弧形的方式绘制圆形
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在同位置先绘制了矩形,方便对比,
    效果

    在这里插入图片描述

    以 canvas.drawArc(new RectF(100,500,400,700),270,-90,true,paintArc1); 为例说明参数

    • 矩形左上角坐标是(100,500) ,右下角坐标是 (400,700) ,从而得到了最大内切椭圆。
    • startAngle :开始点相对比 0° 的角度,顺时针方向(绿色箭头方向)为正方向,所以是 270°。
    • sweepAngle :开始点旋转的角度,逆时针方向(蓝色箭头方向)为负方向,所以是 -90° 。
    • useCenter :如果设为 true ,则包含椭圆中心,即弧形区域是 起点终点间的弧线 + 起点和椭圆中心的直线 + 终点和椭圆中心的直线 围起来的区域。为 false ,弧形区域是 起点终点间的弧线 + 起点到终点的直线 围起来的区域。在这里插入图片描述

    这是没有设置填充效果(默认是填充)的情况,如果设置为描边,如,

    paintArc1.setStrokeWidth(5f);//设置画笔宽度
    paintArc1.setStyle(Paint.Style.STROKE);//设置填充效果为描边
    canvas.drawRect(100,100 ,400,300,paintRect3);// 同位置绘制矩形
    canvas.drawArc(100,100,400,300,0,90,false,paintArc1);
    
    canvas.drawRect(100,500 ,400,700,paintRect3);// 同位置绘制矩形
     anvas.drawArc(new RectF(100,500,400,700),270,-90,true,paintArc1);
    
    canvas.drawRect(500,100 ,900,500,paintRect3);// 同位置绘制矩形
    canvas.drawArc(new RectF(500,100 ,900,500),270,-360,true,paintArc1);//以绘制弧形的方式绘制圆形
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    效果如图,这也可以看出 useCenter 为 true 、false 的差别。
    在这里插入图片描述
    所以,当需要绘制圆形时,drawOval 、drawArc 都是可以用的。

    绘制矩形

    Canvas.drawRect(@NonNull RectF rect, @NonNull Paint paint) :通过 RectF 确定矩形位置并绘制。

    RectF(float left, float top, float right, float bottom) : 初始化 RectF 时根据坐标 (left,top)、(right,bottom) 确定矩形的左上角、右下角。

    private Paint paintCircleGreen = new Paint();
    private Paint paintRectMagenta = new Paint();
    paintRectMagenta.setColor(Color.MAGENTA);
    paintRectMagenta.setFlags(Paint.ANTI_ALIAS_FLAG);
    paintRectGreen.setColor(Color.GREEN);
    paintRectGreen.setFlags(Paint.ANTI_ALIAS_FLAG);
    
    canvas.drawRect(new RectF(100,100,500,300), paintRectMagenta);
    canvas.drawRect(new RectF(500,300,700,500), paintRectGreen);
    
    paintRectGreen.setStyle(Paint.Style.STROKE);// 只描边
    paintRectGreen.setStrokeWidth(5f);
    canvas.drawRect(new RectF(800,300,1000,500), paintRectGreen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    效果,
    在这里插入图片描述

    绘制圆角矩形

    Canvas.drawRoundRect(RectF rect, float rx, float ry, @NonNull Paint paint) :通过 RectF 确定圆角矩形位置并绘制。

    Canvas.drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) : 通过坐标确定圆角矩形位置并绘制,rx 、ry 决定圆角的弧度。

    private Paint paintRoundRect = new Paint();
    paintRoundRect.setColor(Color.MAGENTA);
    paintRoundRect.setFlags(Paint.ANTI_ALIAS_FLAG);
    
    canvas.drawRoundRect(new RectF(100,100,300,300), 10,10,paintRoundRect);
    canvas.drawRoundRect(new RectF(500,100,700,300), 50,50,paintRoundRect);
    
    canvas.drawRoundRect(new RectF(100,400,400,600), 10,10,paintRoundRect);
    canvas.drawRoundRect(new RectF(500,400,800,600), 100,100,paintRoundRect);
    
    paintRoundRect.setStyle(Paint.Style.STROKE);// 只描边
    paintRoundRect.setStrokeWidth(5f);
    canvas.drawRoundRect(new RectF(900,100,1100,300), 10 ,10, paintRoundRect);
    canvas.drawRoundRect(new RectF(900,400,1200,600), 100 ,100, paintRoundRect);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    效果,
    在这里插入图片描述

  • 相关阅读:
    用DIV+CSS技术设计的水果介绍网站(web前端网页制作课作业)
    普冉PY32系列(七) SOP8,SOP10,SOP16封装的PY32F002A/PY32F003管脚复用
    英语语音技巧
    (十三)Java算法:基数排序(详细图解)
    基于MCMC的交通量逆建模(Matlab代码实现)
    分享个人收集或整理的word中常用的vba代码
    Linux脚本之监控系统内存使用情况并给予警告
    【java期末复习题】第4章 面向对象基础
    1.SpringMVC入门案例
    [oeasy]python0016_编码_encode_编号_字节_计算机
  • 原文地址:https://blog.csdn.net/weixin_44021334/article/details/132617646