使用Canvas绘制几何图形

作者: 程序亦非猿 | 来源:发表于2015-10-14 09:01 被阅读3436次

    前言

    这是我学习自定义View系列中的使用Canvas自带方法(drawxx)绘制几何图形笔记.

    Canvas

    The Canvas class holds the “draw” calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).

    Developer Guides: For more information about how to use Canvas, read the Canvas and Drawables developer guide.

    可以看出要使用Canvas,我们还需要一个bitmap(画在什么上),一个原型(画什么),一个Paint(用什么笔画).
    感觉Canvas更像是个媒介.

    PS:Paint不是本文重点,就不提供Paint的相关代码了(其实就换换颜色什么的).
    

    Canvas拥有各种draw方法,不过,这里我只学习记录如何绘制几何图形以及效果:

    1. 直线
    2. 矩形(正方形)
    3. 弧形(扇形)
    4. 椭圆(圆)

    坐标系

    在学习这些知识之前,先来讲讲坐标系.
    在Android中每个View都有着自己的坐标系,都是以自己的左上角的点为原点.
    需要注意的是Y轴正方向是向下的

    坐标系示意图

    点(Point)

    在Android中点除了用(x,y)坐标来表示外,还可以由Point以及PointF来表示,其实它们都封装了x,y,另外再加了一些方法便于使用.
    顺便提一下,它们的区别在于Point的精度为int,而PointF的精度为float,仅此而已,推荐PointF.

    而用canvas画点非常简单:
    public void drawPoint(float x, float y,@NonNull Paint paint)
    只要给定一个(x,y)坐标即可.
    由于点很简单,效果图跟线一起给.

    直线(Line)

    直线即两点的连线,也很简单,只要给出起始点,结束点的坐标即可.
    public void drawLine(float startX, float startY, float stopX, float stopY,@NonNull Paint paint)

    // 画一个点
    canvas.drawPoint(10, 10, mPointPaint);
    // 画两条直线
    canvas.drawLine(0, 0, 0, 300, mLinePaint);
    canvas.drawLine(0, 300, 300, 300, mLinePaint);
    
    Point-Line效果图

    矩形(Rectangle)

    画矩形有以下方法:

    1. public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
    2. public void drawRect(@NonNull RectF rect, @NonNull Paint paint)
    3. public void drawRect(@NonNull Rect r, @NonNull Paint paint)

    先不着急画,我们来看看第一个方法需要我们给定4条边的坐标值,来定位这个矩形,那么它是如何定位的呢?
    很简单:

    1. left,right 是距离Y轴的水平距离
    2. top,bottom 是距离X轴的水平距离

    这样给定四条边的距离后即可确定一个矩形.

    Rect-理解图

    我还有另外一种理解方式,可以把这四个点理解为矩形对角的两个点的坐标(left,top),(bottom,top),
    确定这两个点后,平移x轴,y轴与他们相交,也可以获得该矩形.

    另一种理解

    另外,跟前面的点类似,Android中有Rect以及RectF封装了这四个值以及一些方法,它们的区别跟Point与PointF一样,就不多说了,依然推荐RectF.

    另外还有一个RoundRect值得一提
    public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)

    参数rx,ry代表两个不同的半径.
    PS:这个有个坑:当某一个值为0时,则无效果了.

    canvas.translate(300, 0);
    canvas.drawRoundRect(mArcRectF,0,20,mRectFPaint);
    
    canvas.translate(300, 0);
    canvas.drawRoundRect(mArcRectF,50,70,mRectFPaint);
    
    效果

    弧形(Arc)&扇形

    1. public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,@NonNull Paint paint)
    2. public void drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, @NonNull Paint paint)(API21)

    之前已经提到过RectF,其实这两个方法一样,不过第二个API等级为21.
    那么来理解一下参数:

    1. RectF oval 给定一个矩形,来确定一个内切圆
    2. startAngle 弧形的起始角度
    3. sweepAngle 弧形的角度跨度
    4. useCenter 最后的弧形是否包括圆心(true则为扇形了)

    画了个简易的图,方便理解:

    一张图理解drawArc
    PS: sweepAngle>=360 时则为一个内切圆,无视useCenter.  
    

    椭圆(Oval)&圆(Circle)

    椭圆:

    1. public void drawOval(@NonNull RectF oval, @NonNull Paint paint)
    2. public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)(API21)

    参数理解:前面已经提过,给定一个矩形,即可获得一个内切圆,也就是这个椭圆.

    圆:
    public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint)

    参数理解:(cx,cy)代表圆心的坐标,radius表示半径,这样即可确定一个圆,很好理解.

    PS: 虽然默认提供画圆的方法只有一个,但是由于圆是个特殊的椭圆,只要画椭圆时给定一个正方形也能画圆.
    
    canvas.translate(400, 0);
    mOvalRectF.set(0, 30, 267, 222);//椭圆
    canvas.drawOval(mOvalRectF, mOvalPaint);
    
    canvas.translate(0, 300);
    mOvalRectF.set(0,0,200,200);//设置成正方形
    canvas.drawOval(mOvalRectF, mOvalPaint);
    
    canvas.translate(0, 300);
    canvas.drawCircle(50, 50, 100, mOvalPaint);//直接画正方形
    
    效果

    结语

    好了,使用Canvas画简单的几何图形就到这里了~~
    代码在Github上.

    如果有遗漏,有错误,欢迎指导!!!!
    PS:这个笔记写了两遍,第一遍被自己不小心给还原了,被自己笨哭了!

    另外欢迎关注:
    我的Github
    我的微博
    我的微信公众号:

    微信公众号

    相关文章

      网友评论

      • 64d6294c1705:写的十分好 ,谢谢
        程序亦非猿: @64d6294c1705 谢谢支持
      • 2383a08feca6:canvas.save();//锁画布(为了保存之前的画布状态)
        canvas.translate(10, 10);//把当前画布的原点移到(10,10),后面的操作都以(10,10)作为参照点,默认原点为(0,0)
        drawScene(canvas);
        canvas.restore();//把当前画布返回(调整)到上一个save()状态之前

        canvas.save();//锁画布(为了保存之前的画布状态)
        canvas.translate(160, 10);//把当前画布的原点移到(160,10),后面的操作都以(160,10)作为参照点,
        canvas.clipRect(10, 10, 90, 90);//这里的真实坐标为左上(170,170)、右下(250,250)
        canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
        drawScene(canvas);
        canvas.restore();
      • google_404:6666
        程序亦非猿:@bypain 谢谢
      • MrFu:棒!!
      • 匹诺曹pino:mark 支持
      • 郑鸿翊:自己画东西的时候总是会忘记这些画法,收藏起来,日后必有用处!
        程序亦非猿:@郑鸿翊 我就是因为自己会忘记 才写的这笔记
      • mrwangyong:很喜欢您的文章,支持.每篇必看!!
        程序亦非猿:@roidTest 太感谢你了 多谢支持
      • 小鄧子:来晚了,必须支持。
        程序亦非猿:@小鄧子 谢谢 哈哈

      本文标题:使用Canvas绘制几何图形

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