自定义控件(一)

最近在跟扔物线大婶学自定义控件,其实许多东西之前都用过的,不过时间长就忘了,然后这次就系统的复习一下,顺便记录下来。
自定义绘制,首先要创建好Paint对象,重写onDraw(),把绘制代码写在onDraw()里,这就是自定义绘制最基本的实现。Paint和canvas组合使用可以画出各种各样的图形。

Paint类的常用方法

  • paint.setStyle(Style style) 设置绘制模式
  • paint.setColor(int color) 设置颜色
  • paint.setStrokeWidth(float width) 设置线条宽度
  • paint.setTextSize(float textSize) 设置文字大小
  • paint.setAntiAlias(boolean aa) 设置抗锯齿开关(初始化Paint时可直接设置)

paint.setStyle(Style style)主要有三种样式:FILL,STROKE和FILL_AND_STROKE。FILL 是填充模式,STROKE 是画线模式(即勾边模式),FILL_AND_STROKE 是两种模式一并使用:既画线又填充。它的默认值是 FILL,填充模式。

1.canvas.drawColor()颜色填充

这算是最简单的了,直接canvas.drawColor(Color.Yellow)。类似的方法还有drawColor(Color.parse("")),直接填16进制色值就行,例如drawColor(Color.parse("#F00")),drawColor(Color.parse("#6F00")),drawColor(Color.parse("#CCCCCC")),drawColor(Color.parse("#88880000"))。 drawRGB(int r, int g, int b),drawARGB(int a, int r, int g, int b)
drawColor()
    canvas.drawColor(Color.YELLOW);

2.canvas.drawCircle(float centerX, float centerY, float radius, Paint paint)画圆

前两个参数表示圆的圆心坐标,radius是圆心半径,paint可以设置圆的填充颜色,空心圆还是实心圆还是圆环,还有圆环的宽度等(插一句,从屏幕左上角,向右为X轴正方向,向下为Y轴正方向)


drawCircle()
        //实心圆
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//开启抗锯齿
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(200,200, 150, paint);
        //空心圆
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(700, 200, 150, paint);
        //蓝色实心圆
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(700, 600, 150, paint);
        //空心圆环,环宽20
        paint.setStrokeWidth(20);
        canvas.drawCircle(200, 600, 150, paint);

3.canvas.drawRect(float left, float top, float right, float bottom, Paint paint)画矩形

drawRect()
canvas.drawRect(100,100,400,300,paint);

从上面可以很明显的看到各个参数所代表的意思。矩形的width = right-left,矩形的hight = bottom-top。当宽和高相等时就是正方形。例如,我要画一个宽为300,高为200的矩形,是这样的canvas.drawRect(100,100,400,300,paint)

4.canvas.drawPoint(float x, float y, Paint paint)画点

x 和 y 是点的坐标。点的大小可以通过 paint.setStrokeWidth(width) 来设置;点的形状可以通过 paint.setStrokeCap(cap) 来设置:ROUND 画出来是圆形的点,SQUARE 或 BUTT 画出来是方形的点。


drawPoint()
        //圆点
        paint.setColor(Color.BLACK);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(60);
        canvas.drawPoint(200, 200, paint);
        方点
        paint.setStrokeCap(Paint.Cap.SQUARE);
        paint.setStrokeWidth(60);
        canvas.drawPoint(500,200,paint);

drawPoint()是画单个点,还有两个方法是批量画点,drawPoints(float[] pts, int offset, int count, Paint paint) / drawPoints(float[] pts, Paint paint),

float[] points = {0, 0, 50, 50, 50, 100, 100, 50, 100, 100, 150, 50, 150, 100};每两个数字为一个点

// 绘制四个点:(50, 50) (50, 100) (100, 50) (100, 100)
canvas.drawPoints(points, 2 /* 跳过两个数,即前两个 0 */, 4 /* 坐标个数,也就是两个点*/, paint);
//绘制所有的点
canvas.drawPoints(points,paint);

5.canvas.drawOval(float left, float top, float right, float bottom, Paint paint)画椭圆

left, top, right, bottom 是这个椭圆的左、上、右、下四个边界点的坐标


draw.Oval()
//实心椭圆
paint.setStyle(Style.FILL);
canvas.drawOval(50, 50, 350, 200, paint);
//空心椭圆
paint.setStyle(Style.STROKE);
canvas.drawOval(400, 50, 700, 200, paint);

6.canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint)画线

前两个参数是线的起点坐标,然后两个是终点坐标。


drawLine()
paint.setStrokeWidth(20);//设置线宽
canvas.drawLine(100, 100, 600, 500, paint);paint

画线跟画点类似,也有批量画线的方法drawLines(float[] pts, int offset, int count, Paint paint) / drawLines(float[] pts, Paint paint)

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);  //画所有线
canvas.drawPoints(points, 2 /* 跳过两条线,即4个点,8个数字 */, 3 /* 一共绘制三个点*/, paint);

7.canvas.drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)画圆角矩形

left, top, right, bottom 是四条边的坐标,rx 和 ry 是圆角的横向半径和纵向半径。


drawRoundRect()
//实心圆角矩形
canvas.drawRoundRect(100,100,600,300,30,30,paint);(设置paint填充模式可画空心圆角矩形)

8.canvas.drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 绘制弧形或扇形

drawArc() 是使用一个椭圆来描述弧形的。left, top, right, bottom 描述的是这个弧形所在的椭圆;startAngle 是弧形的起始角度(x 轴的正向,即正右的方向,是 0 度的位置;顺时针为正角度,逆时针为负角度),sweepAngle 是弧形划过的角度;useCenter 表示是否连接到圆心,如果不连接到圆心,就是弧形,如果连接到圆心,就是扇形。


drawArc()
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); // 绘制不封口的弧形

9.canvas.drawPath(Path path, Paint paint) 画自定义图形(重点来了)

Path 可以描述直线、二次曲线、三次曲线、圆、椭圆、弧形、矩形、圆角矩形。把这些图形结合起来,就可以描述出很多复杂的图形。Path 有两类方法,一类是直接描述路径的,另一类是辅助的设置或计算。(详细解释请点这里
下面来重点分析下这个心形是怎么画的

drawPath()

      Path path = new Path(); // 初始化 Path 对象
      //第一步,path添加左边一个扇形
      path.addArc(200, 200, 400, 400, -225, 225);
      //第二步,从第一步完成的地方添加右边的扇形
      path.arcTo(400, 200, 600, 400, -180, 225, false);
      //第三步,从第二部步结束的地方画线,到点(400,542)也就是心形最下面的点,并与起点封闭封闭
      path.lineTo(400, 542);
      //画图
      canvas.drawPath(path, paint);

path可以添加各种形状,然后相互连接起来。


path

path

更多的方法,大家可以自己研究研究。

10.canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 画 Bitmap

绘制 Bitmap 对象,也就是把这个 Bitmap 中的像素内容贴过来。其中 left 和 top 是要把 bitmap 绘制到的位置坐标。

canvas.drawBitmap(bitmap, 200, 100, paint);

11.canvas.drawText(String text, float x, float y, Paint paint) 绘制文字

界面里所有的显示内容,都是绘制出来的,包括文字。 drawText() 这个方法就是用来绘制文字的。参数 text 是用来绘制的字符串,x 和 y 是绘制的起点坐标。
通过 Paint.setTextSize(textSize),可以设置文字的大小。

paint.setTextSize(18);
canvas.drawText(text, 100, 25, paint);
paint.setTextSize(36);
canvas.drawText(text, 100, 70, paint);

12.画柱状图和饼图

练习

这些复杂的图形其实就是把前面讲到的方法综合起来用就可以绘制成想要的图形了。把一些基本的封装起来,再把一些可以设置值和颜色的方法暴露出去,就成了自己的自定义控件。

推荐两个图表类的开源项目,一个android的MPAndroidChart,一个h5页面上可以用的ECharts

以上所有的代码在这里

另外强烈推荐大家关注下扔物线大神的公众号,这是一个系列的教程,每周一篇。

扔物线大婶公众号

推荐阅读更多精彩内容