自定义view_canvas的详细介绍

自定义view_canvas的详细介绍

声明:本文作为总结性文章,特别感谢扔物线相关文章提供的帮助!
简叙

对于Android开发者而言,谷歌提供的原生view控件(例如:TextView 、ImageView和Button等 )往往满足不了UI设计师对于界面的设计需求,因此需要安卓开发者根据UI设计自定义控件,实现良好的展示效果,本文作为 安卓自定义的开发基础,希望对初学者有一定的帮助。
下面会按照自定义view的初级编写、Canvas和Paint的简单介绍和Canvas系列方法三个部分介绍。

  1. 自定义View的初级编写

  1. 创建view类
    自定义view的上手非常容易,根据需要创建自定义view类,例如MyView并继承View,重写其构造方法,注意必须**至少要重写两个CanvesView()**方法,否则无法正常使用自定义的view类,创建好自定义View类后,重写onDraw()方法,至此一个简单的自定义View就创建完成了。

  2. 使用自定义View
    使用自定义View非常简单,在xml布局中添加我们自定义的view即可,注意在使用时必须包含包名,当然由于我们在自定义的View中的onDraw()方法中未进行任何处理,因此我们运行程序时不会显示任何信息,自定义View的关键就是对onDraw()方法的处理。

  3. Canvas和Paint的简单介绍


前面已经介绍了自定义View的简单使用,可以看出自定义View的关键是对onDraw()方法的自定义处理。自定义View可以理解为在画布上作画,Canvas可以看作画布,而Paint则是画笔。Canvas类下面的所有方法都是以draw_开头,Paint则是对画笔属性的设置。可以根据需要参看谷歌官方的CanvasPaint 官方文档。
对于Paint的简单介绍:

  • paint.setStyle();
    包括三种属性:
    FILL:只绘制图形内容,
    FILL_AND_STROKE:即绘制图形内容也绘制图形轮廓,
    STROKE:只绘制图形轮廓,注意该属性的设置是对封性的图形设置的,而对于像直线这样的图形不起作用。
  • paint.setColor();设置画笔的颜色
  • paint.setTextSize();当绘制文字时,设置文字的大小
  • paint.setStrokeWidth();设置线条轮廓的宽度
  • paint.setAntiAlias();设置是否抗锯齿

对于该属性默认设置为false的即默认是不抗锯齿的,也行有人会问,既然抗锯齿显示效果那么好,为什么不默认打开,或者直接将该属性的API取消,直接默认是抗锯齿的,多好啊,其实不是所有的场景都适合抗锯齿设置的,因为之所以出现锯齿现象是因为像素分辨率过低导致的,而不是安卓属性设置原因,在设置为抗锯齿时,谷歌的处理结果是修改像素边缘的颜色,使其肉眼看起来更平滑,这样出现的另一个问题是图像的颜色失真,如下图所示。
这里写图片描述

3.Canvas的系列方法

以上是对Canvas和Paint的简单介绍,下面重点讲解Canvas的系列方法,上面提到Canvas系列方法都是以draw_开头的,对于对于图形的绘制大致可以分为两种,一种是谷歌原生的绘制例如:canvas.drawArc()、canvas.drawLine和canvas.drawText等,我们可以根据需求调用相应的API,还有一种是根据需要自定义图形。
在讲解Canvas相关方法之前,我们首先要明白一个知识点,对于安卓的坐标系,不同于我们数学中的常见坐标系,安卓中的坐标系与数学中的坐标系最大的区别是Y轴朝下为正,对于某个View的坐标为(300,300)是指向右300,向下300。

这里写图片描述
1. Canvas相关方法
①画矩形:drawRect(float left, float top, float right, float bottom, Paint paint)

         paint1.setStrokeWidth(5);
        paint1.setStyle(Paint.Style.STROKE);//只绘制轮廓
        canvas.drawRect(150,500,450,800,paint1);
        
        paint.setStyle(Paint.Style.FILL);//绘制图形
        canvas.drawRect(500,500,800,800,paint);

这里写图片描述
②画点:drawPoint(float x, float y, Paint paint)
其中x和y表示是点的坐标值,点的大小通过paint.setStrokeWidth()来设置,点的形状通过paint.setStrokeCap()来设置,端点有圆头 (ROUND)、平头 (BUTT) 和方头 (SQUARE) 三种。

        paint1.setStrokeCap(Paint.Cap.ROUND);//设置为圆头
        canvas.drawPoint(100, 100, paint1);
        paint1.setStrokeCap(Paint.Cap.SQUARE);//设置为方头
        canvas.drawPoint(200, 100, paint1);

这里写图片描述
对于点的操作,还有一个API是批量的绘制点,画点(批量) drawPoints(float[] pts, int offset, int count, Paint paint) / drawPoints(float[] pts, Paint paint) 。
pts:是指点坐标数组,两个作为一组表示坐标的x轴和y轴
offset:起始数组的索引
count:绘制点的坐标数组长度,例如绘制4个点,则该值为8
③画椭圆: drawOval(float left, float top, float right, float bottom, Paint paint)
其中参数值是椭圆的左上右下的边界点坐标值。

paint.setStyle(Style.FILL);  
canvas.drawOval(50, 50, 350, 200, paint);

paint.setStyle(Style.STROKE);  
canvas.drawOval(400, 50, 700, 200, paint);  

这里写图片描述
④画线: drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
其中startX和startY表示起始坐标值,stopX和stopY表示结束坐标值

canvas.drawLine(200, 200, 800, 500, paint);  

这里写图片描述
同样对于划线,谷歌提供了批量操作的API(drawLines)

float[] points = {20, 20, 120, 20, 70, 20, 70, 120, 20, 120, 120, 120, 150, 20, 250, 20, 150, 20, 150, 120, 250, 20, 250, 120, 150, 120, 250, 120};  
canvas.drawLines(points, paint); 

这里写图片描述

⑤画圆角矩形: drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
其中前面参数类似于椭圆形的绘制,表示左上右下,rx和ry表示圆角的横向半径和纵向半径,横向半径是指圆的边缘与X轴平行相切,纵向半径指圆的边缘与Y轴平行相切。另外,它还有一个重载方法 drawRoundRect(RectF rect, float rx, float ry, Paint paint),让你可以直接填写 RectF 来绘制圆角矩形。

canvas.drawRoundRect(100, 100, 500, 300, 50, 50, paint);  

这里写图片描述

⑥绘制弧形或扇形: drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
弧形或者扇形的绘制可以理解为对于椭圆形的裁切处理,前面几个参数与椭圆形表示的相同,startAngle表示起始的角度(X轴正方向为刻度的0度);sweepAngle扫描覆盖的角度,参数设置时,正数表示顺时针旋转的度数,负数表示逆时针旋转的度数;useCenter表示是否连接圆点,true表示连接,绘制的是扇形,false表示不连接,绘制的是弧形。

paint.setStyle(Paint.Style.FILL); // 填充模式  
canvas.drawArc(200, 100, 800, 500, -110, 100, true, paint); // 绘制扇形  
canvas.drawArc(200, 100, 800, 500, 20, 140, false, paint); // 绘制弧形  
paint.setStyle(Paint.Style.STROKE); // 画线模式  
canvas.drawArc(200, 100, 800, 500, 180, 60, false, paint); // 绘制不封口的弧形  

这里写图片描述
⑦画 Bitmap: drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
参数bitmap是绘制的图片资源,left和top是指绘制的图形坐上角坐标值
这里写图片描述
⑧绘制文字: drawText(String text, float x, float y, Paint paint)
参数text是绘制的文字内容,x和y是文字的左下角位置的坐标值,在设置paint.setStyle(Paint.Style.STROKE)时,表现为空心的字体。
这里写图片描述
以上就是对于谷歌提供的常见的图形绘制的讲解,下面讲解自定义图形的绘制。
2、自定义图形的绘制
自定义的图形的绘制,其实是根据项目需要组合已有的图形,这里用到一个关键的类Path,添加不同API实现对自定义图形的绘制。
path.addArc(); //添加扇形
path.addCircle();//添加圆弧
path.quadTo();//二次元贝塞尔曲线
path.rCubicTo();//三次元贝塞尔曲线
path.close();//封闭图形,当Paint.Style 为 FILL 或 FILL_AND_STROKE时,Path 会自动封闭子图形。

对于交叉图形的填充方式,Path提供的Path.setFillType(Path.FillType ft) 来设置,包括四种方式,

  • EVEN_ODD
  • WINDING (默认值)
  • INVERSE_EVEN_ODD
  • INVERSE_WINDING
    其中后面的两个带有 INVERSE_ 前缀的,只是前两个的反色版本,所以只要把前两个,即 EVEN_ODD 和 WINDING,搞明白就可以了。
    可以通过一个简单的方式来确定,
    EVEN_ODD时(奇偶原则)
    在图形中的点任意画一条射线,计算与图形轮廓交叉点的个数(相切不算),数量为奇数所在区域填充,偶数不填充。
    这里写图片描述
    WINDING(非零环绕数原则)
    首先需要确定绘制的图形都是有方向的,
    对于同方向的,则射线穿过的数据为0是外部,不涂色,否则为内部涂色。
    对于不同方向的,穿过顺时针加1,穿过逆时针减1,最终相加为结果,为0则为外部,否则为内部需涂色。
    因此这里的涂色计算比较复杂,这里不在细讲。
    这里写图片描述

至此对于简单的Canvas的图形绘制就讲解结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值