自定义View——drawXXX

前言

既然要自定义View,那么自然少不了各种绘制,既然要绘制,那么自然离不开Canvas和Paint,那么本篇文章就介绍一下,canvas的各种drawXXX方法和Paint一些常用方法。

Android中的坐标系

Android中的坐标系的X轴与传统的坐标系一致,但是Y轴与传统的坐标系不同,方向是相反的。


Paint常用方法

  • Paint.setStyle(Style style) 设置绘制模式

  • Paint.setColor(int color) 设置颜色

  • Paint.setStrokeWidth(float width) 设置线条宽度

  • Paint.setTextSize(float textSize) 设置文字大小

  • Paint.setAntiAlias(boolean aa) 设置抗锯齿开关


    抗锯齿关闭与开启
  • Paint.setDither(boolean dither) 设置防抖动开关


    防抖动未开启

    防抖动开启

onDraw()

以下所有操作均是在onDraw()中进行的,把绘制代码写在 onDraw() 里面,就是自定义绘制最基本的实现。

canvas.drawColor(@ColorInt int color) 颜色填充

在整个绘制区域统一涂上指定的颜色,当然你也可以传入带透明度的颜色,达到遮罩层的效果

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.YELLOW);
    }
drawColor

canvas.drawCircle 画圆

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

  • centerX,centerY:确定圆心的坐标
  • radius:确定圆的半径
canvas.drawCircle(300f, 300f, 200f, mPaint);
drawCircle

补充

Paint.setColor(int color)改变画笔的颜色

mPaint.setColor(Color.BLUE);
canvas.drawCircle(200f, 400f, 100f, mPaint);
BLUE

Paint.setStyle(Paint.Style style)改变画笔的风格

Style有三种,分别是FILL, STROKE 和 FILL_AND_STROKE。

  • FILL:填充模式(默认)
  • STROKE:勾边模式
  • FILL_AND_STROKE:两种模式一并使用,既画线又填充
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(500f, 100f, 100f, mPaint);
STROKE

Paint.setStrokeWidth(float width)设置线条宽度

mPaint.setStrokeWidth(20f);
canvas.drawCircle(500f, 500f, 100f, mPaint);
setStrokeWidth

canvas.drawRect 画矩形

画矩形有三种方法

  • drawRect(RectF rect, Paint paint)
  • drawRect(Rect rect, Paint paint)
  • drawRect(float left, float top, float right, float bottom, Paint paint)
  • left,top,right,bottom:这4个参数的意思我在下图中标记出来

这里有朋友可能就要问了,Rect和RectF有什么区别?
简单来说,最大的不同就是精度不同,一个传int类型,传float类型,至于其他的不同这里暂时先不说,也用不到。

canvas.drawRect(200f,100f,400f,300f,paint);
等价于
RectF rectF = new RectF(200f,100f,400f,300f);
canvas.drawRect(rectF,paint);
drawRect

canvas.drawPoint 画点

canvas.drawPoint(float x, float y, Paint paint)

  • x,y:圆点的坐标
  • 点的大小:paint.setStrokeWidth(width)
  • 点的形状:paint.setStrokeCap(cap) ,ROUND圆形,SQUARE或BUTT方形(默认)。
paint.setStrokeWidth(40);

paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawPoint(100f,100f,paint);

paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawPoint(600f,300f,paint);
drawPoint

canvas.drawPoints 批量画点

批量画点有两种方法

  • canvas.drawPoints(float[] pts, int offset, int count, Paint paint)
  • canvas.drawPoints(float[] pts, Paint paint)
  • pts:点的坐标数组
//绘制八个点(50,50)(100,50)(150,50)(200,50)
//(50,100)(100,100)(150,100)(200,100)
float[] pts = {50,50,100,50,150,50,200,50,50,100,100,100,150,100,200,100};
canvas.drawPoints(pts,paint);
drawPoints
  • offset:从数组中的第几个index开始取
  • count:取几个

举个例子,我们传offset为2,count为4,再传offset为1,count为4看看效果

显然这两个点的坐标为(100,50)和(150,50)


offset为2

这两个点的坐标为(50,100)和(50,150)


offset为1

canvas.drawOval 画椭圆

画椭圆有两种方法

  • drawOval(RectF rect, Paint paint)
  • drawOval(float left, float top, float right, float bottom, Paint paint)
canvas.drawOval(300f,300f,600f,450f,paint);
drawOval

其实我们可以理解为下图
oval.png

当然我们也可以使用Paint.setStyle(Paint.Style style)绘制出空心椭圆,这里就不演示了,参考上面的drawRect()。

canvas.drawLine 画线

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

  • startX,startY:起始点的坐标
  • stopX,stopY:结束点的坐标

两点确定一条直线。。。,当然我们也可以使用paint.setStrokeWidth()改变线的宽度。

canvas.drawLine(100,100,400,100,paint);
paint.setStrokeWidth(10);
canvas.drawLine(100,300,400,300,paint);
drawLine

canvas.drawLines 批量画线

批量画线有两种方法

  • canvas.drawLines(float[] pts, int offset, int count, Paint paint)
  • canvas.drawLines(float[] pts, Paint paint)

这里的参数与上面画点是一样的。

//(50,50)(150,50)(100,0)(100,150)(100,50)(50,150)(100,50)(150,150)
float[] pts = {50,50,150,50,100,0,100,150,100,50,50,150,100,50,150,150};
canvas.drawLines(pts,paint);

本来想画个李字的,想了想,点太多了,画个木字算了,哈哈哈,请原谅我懒。。。


drawLines

canvas.drawRoundRect 画圆角矩形

  • rx,ry:圆角的横向半径和纵向半径

画圆角矩形有两种方法

  • drawRoundRect(RectF rect, float rx, float ry, Paint paint)
  • drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
 canvas.drawRoundRect(200f,300f,600f,500f,20f,20f,paint);
drawRoundRect

canvas.drawArc 绘制弧形或扇形

canvas.drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

  • left,top,right,bottom:还是用来确定绘制位置的
  • startAngle:起始角度
  • sweepAngle:划过的角度
  • useCenter:是否连接到圆心

这里首先我们要确定一个概念,0度在哪里,直接贴图


角度坐标图
RectF rectF = new RectF(300f,200f,500f,400f);

paint.setStyle(Paint.Style.FILL);//填充模式
canvas.drawArc(rectF, -110f, 100f, false, paint);//不连接圆心的填充弧形
canvas.drawArc(rectF,20f,140f,true,paint);//连接圆心的填充扇形

paint.setStyle(Paint.Style.STROKE);//钩边模式
canvas.drawArc(rectF,-160f,40f,false,paint);//不连接圆心的弧形
canvas.drawArc(rectF,170f,20f,true,paint);//连接圆心的扇形
drawArc

canvas.drawBitmap 画 Bitmap

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

canvas.drawBitmap(bitmap,20f,20f,paint);
drawBitmap

canvas.drawText 绘制文字

canvas.drawText(String text, float x, float y, Paint paint)

paint.setTextSize(20);
canvas.drawText("LXT",50f,100f,paint);

paint.setTextSize(30);
canvas.drawText("LXT",50f,200f,paint);

paint.setTextSize(40);
canvas.drawText("LXT",50f,300f,paint);

paint.setTextSize(50);
canvas.drawText("LXT",50f,400f,paint);
drawText
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容