Android笔记 自定义View(五):Canvas使用之绘制点、线、几何图形

本次继续了解下怎么绘制点、线和几何图形

目录

一、绘制点

二、绘制线

三、绘制几何图形

1、矩形和圆角矩形:

2、绘制圆和椭圆

3、绘制圆弧

四、总结


一、绘制点

查看api我们可以知道Canvas中画点的方法:

/*
* @param
*  x x轴坐标
*  y y轴坐标
*  paint 画笔
* 绘制单个点。
*/
public void drawPoint(float x, float y, @NonNull Paint paint)

/*
* @param
*  pts 两个值(x轴坐标,y轴坐标)为一组的数组。且为2的倍数,否则报错。例如:
*  {100,100,200,200}:表示(100,100)和(200,200)两个点。
*  paint 画笔
* 绘制一组点。
*/
public void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint)

/*
* @param
*  pts 同上
*  offset 跳过pts中offset个值
*  count 以pts中第offset+1个值到第offset+1+count值计算坐标画点,
*        不足以0为最后一个点的y坐标
*  paint 画笔
* 绘制一组点。
*/
public void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
            @NonNull Paint paint)

我们需要注意的两点:

  • float数组pts的值必须是2的倍数,否则报错
  • 最后一个方法offset和count参数代表的意思就可以了。

我们看下效果:

代码:

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(5);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPoint(50,50,mPaint);
        //绘制一组点,坐标位置由float数组指定
        canvas.drawPoints(new float[]{
                50,100,
                100,100,
                150,100,
                200,100,
                250,100,
        },mPaint);

        //绘制一组点中指定的几个坐标
        canvas.drawPoints(new float[]{
                50,150,
                100,150,
                150,150,
                200,150,
                250,150,
        },2,4,mPaint);
    }

当我们设置Paint的宽度比较大时发现画出来的点都是矩形的,想画出圆形的点怎么办?我们只要设置一下Paint的笔帽就好了,如下:

/*
* Paint.Cap的三个枚举值
*  BUTT:没有笔帽
*  ROUND:半圆笔帽
*  paint 矩形笔帽
* 在绘制直线时体现更加明显
*/
mPaint.setStrokeCap(Paint.Cap.ROUND);

二、绘制线

同样,我们通过API看看Canvas绘制线的方法:

/*
* @param
*  startX  线起始点的x坐标
*  startY  线起始点的y坐标
*  stopX 线终点的x坐标
*  stopY 线终点的y坐标
*  paint 画笔
* 绘制一条线段使用指定的起点、终点,x,y坐标,使用指定的画笔。
* 注意,一条线默认是实线,所以画笔的样式被忽略。退化线(长度为0)将不是绘制。
*  另外,绘制一组线的方法同drawPont类似,不过将两个坐标值换成4个
*/
public void drawLine (float startX, float startY, float stopX, float stopY, Paint paint)
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint)
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
            @NonNull Paint paint)

可以看到与绘制点的方法类似。需要注意的是最后一个方法:

  • 当计数的坐标点小于4位,则会报错
  • 当计数的坐标最后一组不满足4个坐标点则默认不去绘制最后一组。

效果:

 public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(5);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 在坐标(50,50)(50,250)之间绘制一条直线
        canvas.drawLine(50,50,50,250,mPaint);   
        // 绘制一组线 每四数字(两个点的坐标)确定一条线
        canvas.drawLines(new float[]{               
                100,50,200,50,
                100,100,200,100,
                100,150,200,150,
                100,200,200,200,
                100,250,200,250
        },mPaint);

        //绘制数组中指点坐标的线 每四数字(两个点的坐标)确定一条线
        canvas.drawLines(new float[]{               
                250,50,350,50,
                250,100,350,100,
                250,150,350,150,
                250,200,350,200,
                250,250,350,250
        },12,8,mPaint);

    }

如图:

绘制点的时候,我们说到Paint.setStrokeCap(Paint.Cap.ROUND)方法。现在我们看下区别,为了效果明显将画笔的宽度跳粗:

另外,这是绘制直线,如果我们需要绘制虚线、折线等一些特殊效果的线要怎么做?在后面介绍Path类时我们在说。

三、绘制几何图形

1、矩形和圆角矩形:

通过Canvas类中,有下面几个方法绘制矩形和圆角矩形:

/*
* @param
*  left 要绘制的矩形的左边
*  top 要绘制的矩形的上边
*  right 要绘制的矩形的右边
*  bottom 要绘制的矩形的下边
*  paint  绘制区域的使用的画笔 
* 在指定的区域绘制使用指定的画笔。绘制矩形。
*/
public void drawRect(float left, float top, float right, float bottom, 
            @NonNull Paint paint)

/*
* @param
*  rect 绘制的区域
* 在指定的区域绘制使用指定的画笔。绘制矩形。
*/
public void drawRect(@NonNull Rect r, @NonNull Paint paint)
public void drawRect(@NonNull RectF rect, @NonNull Paint paint)

/*
* @param
*  rect 绘制区域
*  rx 圆角圆弧X轴方向上的半径
*  ry 圆角圆弧y轴方向上的半径
*  paint  绘制区域的使用的画笔 
* 在指定的区域绘制使用指定的画笔。绘制圆角矩形。
*/
public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)
public void drawRoundRect(float left, float top, float right, float bottom, 
            float rx,float ry,@NonNull Paint paint)

上面几个方法都很简单,注释都已经说明。在绘制圆角矩形时需要注意:

ps:圆角矩形的角是椭圆的圆弧,上面的参数rx和ry其实是椭圆的两个半径。当在rx为宽度的一半,ry为高度的一半时,刚好是一个椭圆,而当rx大于宽度的一半,ry大于高度的一半时,实际上是无法计算出圆弧的,所以drawRoundRect对大于该数值的参数进行了限制(修正),凡是大于一半的参数均按照一半来处理。圆角矩形示意图如下:

代码:

    private void initPaint() {
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.DKGRAY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制路径,没有做处理
        canvas.drawRect(new RectF(50,50,150,100),mPaint);
        canvas.drawRoundRect(new RectF(50,120,150,200),3,5,mPaint);
    }

效果图:

2、绘制圆和椭圆

Canvas绘制圆和椭圆的方法如下:

/*
* @param
*  oval 绘制椭圆的矩形边界
*  paint  绘制区域的使用的画笔 
* 在指定的区域绘制使用指定的画笔。绘制椭圆。
*/
public void drawOval(@NonNull RectF oval, @NonNull Paint paint)
public void drawOval(float left, float top, float right, float bottom, 
            @NonNull Paint paint)
  
/*
* @param
*  cx 绘制的圆中心的x坐标
*  cy 绘制的圆中心的y坐标
*  radius 绘制的圆半径
* 在指定的区域绘制使用指定的画笔。绘制圆。
*/
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) 

绘制椭圆实际上就是绘制一个矩形的内切椭圆,原理如下图:

代码实现:

    private void initPaint() {
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.DKGRAY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制路径,没有做处理
        canvas.drawCircle(100,100,50,mPaint);
        canvas.drawOval(new RectF(180,50,280,120),mPaint);
    }

效果图:

3、绘制圆弧

方法说明:

/*
* @param
*  oval 绘制圆弧的矩形边界
*  startAngle 绘制圆弧的起始角(度)
*  sweepAngle 绘制的圆弧的顺时针扫过的弧度(度)
*  useCenter 是否包含圆弧的中心
*  paint 画笔
* 在指定的区域绘制使用指定的画笔。绘制圆弧。
*/
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,我们看下它们具体效果:

代码实现:

    private void initPaint() {
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.DKGRAY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        RectF rectF = new RectF(50,50,250,200);
        // 绘制背景矩形
        mPaint.setColor(Color.GRAY);
        canvas.drawRect(rectF,mPaint);
        // 绘制圆弧
        mPaint.setColor(Color.BLUE);
        canvas.drawArc(rectF,0,90,false,mPaint);

        RectF rectF2 = new RectF(50,250,250,400);
        // 绘制背景矩形
        mPaint.setColor(Color.GRAY);
        canvas.drawRect(rectF2,mPaint);
        // 绘制圆弧
        mPaint.setColor(Color.BLUE);
        canvas.drawArc(rectF2,0,90,true,mPaint);
    }

效果:

如果我只需要弧线,那怎么办呢?只要改变Paint的模式就好。

代码:

   mPaint.setStyle(Paint.Style.STROKE);

效果:

椭圆、圆、矩形实现同上。

ps:在绘制椭圆或者圆弧时,如果传递进来的是一个长宽相等的矩形(即正方形),那么绘制出来的实际上就是一个圆。

四、总结

本次通过Canvas与Paint结合使用,绘制了一些点、线、几何图形。实现比较简单,下篇继续绘制位图。

祝:工作顺利!

 

原文链接:加载失败,请重新获取