一、简述

  1. 本文主要包含Canvas(画布)与Paint(画笔),详细介绍了相关api。

  2. canvas的所有的单位均为像素,下文demo仅适配分辨率1080*1920的屏幕。

  3. 关于view基础及dp与px的转换可以看View位置及触摸事件这篇文章。

  4. 请注意一个问题:如果在onDraw方法中绘制的,但是onDraw方法没有走,请在构造函数中添加setWillNotDraw(false);

解释:设置view是否更改,如果开发者用自定义的view,重写onDraw()应该将调用此方法设置为false,这样程序会调用自定义的布局。

Canvas绘图 - 图1

二、Paint(画笔)

  1. 创建画笔:Paint p = new Paint();

  2. 给画笔设置颜色:p.setColor(Color.RED);

  3. 设置绘制的文字大小(单位是px):p.setTextSize(60);

  4. 设置画笔的锯齿效果(true是去除):p.setAntiAlias(true);

  5. 设置风格:p.setStyle(Paint.Style.FILL);,默认样式就是填充,常用的还有设置空心Paint.Style.STROKE

  6. 重置画笔:p.reset();

  7. 设置渐变色:使用Shader对象

    1. Shader类专门用来渲染图像以及一些几何图形,请看下面的代码及注释: ```java /**
    • Shader类专门用来渲染图像以及一些几何图形
    • LinearGradient是Shader的子类,用来进行梯度渲染
    • Shader类的使用,需要先构建Shader对象,然后通过Paint的setShader方法设置渲染对象,
    • 然后设置渲染对象,然后再绘制时使用这个Paint对象即可。 *
    • @param x0 起始的x坐标
    • @param y0 起始的y坐标
    • @param x1 结束的x坐标
    • @param y1 结束的y坐标
    • @param colors 颜色数组
    • @param positions 这个也是一个数组用来指定颜色数组的相对位置 如果为null 就沿坡度线均匀分布
    • @param tile 渲染模式 */ Shader mShader = new LinearGradient(0, 0, 100, 100, new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
      1. Color.LTGRAY}, null, Shader.TileMode.REPEAT);
      ```
  8. 设置Shader:p.setShader(mShader);

  9. 清除Shader:我尝试使用p.setShader(null);可以取消,并且没有影响,当然,也可以使用重置画笔p.reset();

三、Canvas(画布)

注意:canvas是onDraw方法中的,我是直接继承布局在onDraw方法中画的,没有使用SurfaceView或Bitmap

  1. 绘制文字
  1. /**
  2. * @param text 文本
  3. * @param x 水平方向起点
  4. * @param y 竖直方向的文字底部
  5. * @param paint 画笔
  6. */
  7. canvas.drawText("画圆:", 50, 100, p);
  1. 画圆
  1. /**
  2. * 画圆
  3. * @param cx 圆心x坐标
  4. * @param cy 圆心y坐标
  5. * @param radius 半径
  6. * @param paint 画笔
  7. */
  8. canvas.drawCircle(300, 80, 50, p);
  1. 画线条
  1. /**
  2. * 画线条
  3. * @param startX 起点x坐标
  4. * @param startX 起点y坐标
  5. * @param stopX 终点x坐标
  6. * @param stopY 终点y坐标
  7. * @param paint 画笔
  8. */
  9. canvas.drawLine(500, 225, 700, 225, p);
  1. 绘制矩形
  1. /**
  2. * 绘制矩形(两点确定位置,左上角与右下角)
  3. * @param left 左上角x
  4. * @param top 左上角y
  5. * @param right 右下角x
  6. * @param bottom 右下角y
  7. * @param paint:绘制时所使用的画笔。
  8. */
  9. canvas.drawRect(300, 350, 500, 400, p);
  1. 画点
  1. /**
  2. * x,y坐标
  3. */
  4. //画一个点
  5. canvas.drawPoint(500, 1200, p);
  6. //画多个点
  7. canvas.drawPoints(new float[]{600, 1200, 650, 1250, 700, 1200}, p);
  1. 画图片(贴图)
  1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
  2. /**
  3. * @param bitmap The bitmap to be drawn
  4. * @param left 左上角x坐标
  5. * @param top 左上角y坐标
  6. * @param paint 画笔
  7. */
  8. canvas.drawBitmap(bitmap, 360, 1300, p);
  1. 画弧线、扇形,椭圆
  1. 使用到了RectF,先介绍下这个
  1. /**
  2. * 表示一块矩形区域(left <= right and top <= bottom)
  3. * @param left 左上角x
  4. * @param top 左上角y
  5. * @param right 右下角x
  6. * @param bottom 右下角y
  7. */
  8. RectF oval1 = new RectF(800, 50, 900, 100);
  1. 绘制
  1. /**
  2. * oval:圆弧所在的RectF对象。
  3. * startAngle:圆弧的起始角度。
  4. * sweepAngle:圆弧的角度。
  5. * useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示。
  6. * paint:绘制时所使用的画笔。
  7. */
  8. // 画弧线(画弧线是要同时设置画笔样式为Paint.Style.STROKE)
  9. canvas.drawArc(oval1, 180, 180, false, p);
  10. // 画扇形
  11. canvas.drawArc(oval2, 200, 130, true, p);
  12. // 画椭圆
  13. oval2.set(650, 450, 900, 650);
  14. canvas.drawOval(oval2, p);
  1. 扩展:画笑脸
  1. /**
  2. * 画笑脸方法:创建一个RectF区域(这个区域仅容纳第一笔)画第一笔,
  3. * 第一笔绘制完成修改RectF区域画第二笔,依次类推
  4. */
  5. canvas.drawArc(oval1, 180, 180, false, p);//小弧形
  6. /**
  7. * 设置RectF布局,参数与创建RectF相同
  8. */
  9. oval1.set(950, 50, 1050, 100);
  10. canvas.drawArc(oval1, 180, 180, false, p);//小弧形
  11. oval1.set(850, 100, 1000, 200);
  12. canvas.drawArc(oval1, 0, 180, false, p);//小弧形
  1. 画圆角矩形
  1. RectF oval3 = new RectF(500, 880, 700, 1000);// 设置个新的长方形
  2. //第二个参数是x半径,第三个参数是y半径
  3. canvas.drawRoundRect(oval3, 15, 15, p);
  1. 画多边形与贝塞尔曲线
  1. 依旧先介绍下用到的类Path(ps:此处感谢百度翻译):路径类封装的复合(多个轮廓)几何路径组成的直线段,二次曲线,三次曲线。它可以绘制画布上绘制路径(路径、油漆),要么填充或抚摸(根据油漆的风格),也可以用于裁剪或绘画路径上的文本。

  2. 画三角形,多边形的画法跟三角形是一样的

  1. Path path = new Path();
  2. path.moveTo(500, 750);// 此点为多边形的起点
  3. path.lineTo(400, 850);
  4. path.lineTo(600, 850);
  5. path.close(); // 使这些点构成封闭的多边形
  6. canvas.drawPath(path, p);
  1. 画贝塞尔曲线:
  1. Path path2 = new Path();
  2. path2.moveTo(500, 1050);//设置Path的起点
  3. //设置贝塞尔曲线的控制点坐标和终点坐标
  4. path2.quadTo(600, 950, 700, 1050);
  5. path2.quadTo(800, 1150, 900, 1050);
  6. canvas.drawPath(path2, p);

四、源码地址

项目源码https://github.com/sdwfqin/AndroidSamples