自定义View指南之绘制篇

绘制:简单来说也就是画画,就是把想展示的效果在页面中展示出来

1. 如何实现? 

关键:绘制方法有几个,最常用的是重写onDraw()方法,负责主体内容绘制

定义类继承自View,重写onDraw方法,准备工作就绪,这里我们自定义一个画图类

public class CustomizePaint extends View {
    ...

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 这里写你的自定义绘制代码
        ...
    }

    ...
}

2. 在哪里绘制什么?

刚刚好,就在我们重写的onDraw方法中提供给我们一个Canvas,直译:画布;很形象吧,我们的杰作就在这块画布上诞生。

画圆?画线?画字?画图片?别急,canvas不止是一个画布,它还为我们提供了一系列方便的模具,让我们可以快速上手实现一些简单图形的绘制。

先说一下坐标系:每个View都有自己的坐标系,view左上角为该坐标系的原点, 沿坐标原点向右为x轴正方向,向下为y轴正方向

canvas的官方api文档(科学上网哦):https://developer.android.com/reference/android/graphics/Canvas.html

可以直接看官方文档,以下是部分的api说明:

canvas的draw-xxx系列

API功能说明备注(参数说明)

drawCircle(float cx, float cy, float radius, Paint paint)

画圆圆心坐标、半径

drawColor(long color, BlendMode mode)

drawARGB(int a, int r, int g, int b)

drawRGB(int r, int g, int b)

区域上色mode参数为绘制模式,放在后面细讲
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)画线线条的起始点坐标
drawRect(float left, float top, float right, float bottom, Paint paint)画矩形矩形四条边坐标
drawOval(float left, float top, float right, float bottom, Paint paint)画椭圆想象你要绘制椭圆的外切矩形,参数为矩形的四条边坐标,只能绘制横着或竖着的圆,不能绘制斜的
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)画圆角矩形相当于先画直角矩形,沿四个角画横纵向半径分别为rx,ry的椭圆形成的样子
drawPoint(float x, float y, Paint paint)画点 
drawPoints(float[] pts, int offset, int count, Paint paint)批量画点

pts是绘制点组成的数组,数组中两两成一对坐标,offset是从第几个数开始绘制,count为绘制几个数字

drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)画弧形或扇形前四个参数描述扇形所在的椭圆,然后是弧度的起始和划过的弧度,以x轴向右为0度位置,顺时针为正,逆时针为负角度,useCenter表示是否连接到圆心,连接为扇形,否则为弧形
drawPath(Path path, Paint paint)画任意路径可定制性更高
drawText(String text, float x, float y, Paint paint)画字 
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)画图片 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

drawPath额外说明:

Path可以描述直线,二次曲线,三次曲线,圆,椭圆,矩形,弧形等

Path的官方文档:https://developer.android.com/reference/android/graphics/Path

API说明备注
add-xxx方法(主要是添加封闭图形)
addCircle(float x, float y, float radius, Path.Direction dir)画封闭的圆dir:画圆的路径方向,顺时针(cw)和逆时针(ccw),只在需要填充图形且图形出现自相交时判断填充范围
addOval(RectF oval, Path.Direction dir)添加椭圆 
addRect(RectF rect, Path.Direction dir) 添加矩形 
addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)添加圆角矩形 
addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)添加弧形addArc为使用了forceMoveTo为true的简化版arcTo xxxTo方法
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)画线,直线或曲线forceMoveto画弧形的过程中是否和之前的轨迹自动衔接,true为断开独立绘制,false为有线进行连接
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)画三次贝塞尔曲线 
lineTo(float x, float y)画目标点为(x,y)的直线 
moveTo(float x, float y)移动到(x,y)位置,并不画线 
quadTo(float x1, float y1, float x2, float y2)画二次贝塞尔曲线   

rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

rLineTo(float dx, float dy)

rMoveTo(float dx, float dy)

rQuadTo(float dx1, float dy1, float dx2, float dy2)

 r是relative的缩写,和没有r的方法区别在于起点位置,绝对位置的起点位置为(0,0),相对位置的起点为上一次path路径的终点
close() 封闭当前图形 连接起点和终点  

 

LineTo和rLineTo:

        

        

示例:

        // 绘制背景颜色
        canvas.drawColor(Color.parseColor("#E4BCB2"));
        // 第一行第一个
        canvas.drawCircle(100, 100, 50, strokePaint);
        // 第一行第二个
        canvas.drawRect(250, 50, 400, 150, strokePaint);
        // 第一行第三个
        canvas.drawRect(500, 50, 700, 150, strokePaint);
        canvas.drawOval(500, 50, 700, 150, strokePaint);
        // 第一行第四个
        canvas.drawRoundRect(800, 50, 1000, 150, 30, 30, strokePaint);
        canvas.drawCircle(830, 80, 30, strokePaint);
        canvas.drawCircle(970, 80, 30, strokePaint);
        canvas.drawCircle(830, 120, 30, strokePaint);
        canvas.drawCircle(970, 120, 30, strokePaint);
        // 画线
        canvas.drawLine(0, 200, 1300, 200, strokePaint);
        // 画点
        pointPaint.setStrokeWidth(30); // 设置点的大小
        pointPaint.setStrokeCap(Paint.Cap.ROUND); // 设置点的形状 BUTT或SQUARE为方形点,ROUND为圆形点
        canvas.drawPoint(100, 250, pointPaint);
        // 批量画点
        pointPaint.setStrokeCap(Paint.Cap.SQUARE);
        float[] points = {200, 250, 350, 250, 275, 350};
        canvas.drawPoints(points, 0, 6, pointPaint);
        // 绘制弧形
        canvas.drawArc(500, 250, 600, 350, 0, -90, false, strokePaint);
        // 绘制扇形 圆的1/4右上角
        canvas.drawArc(800, 250, 900, 350, 0, -90, true, strokePaint);

        canvas.drawLine(0, 400, 1300, 400, strokePaint);

        canvas.drawCircle(465, 545, 40, strokePaint);
        canvas.drawCircle(465, 545, 25, strokePaint);
        canvas.drawCircle(635, 545, 40, strokePaint);
        canvas.drawCircle(635, 545, 25, strokePaint);
        canvas.drawCircle(550, 600, 101, strokePaint);
        canvas.drawCircle(550, 600, 100, pinkPaint);
        canvas.drawOval(490, 610, 610, 690, whitePaint);
        blackPaint.setColor(Color.BLACK);
        canvas.drawOval(520, 638, 580, 678, blackPaint);
        float[] eyePoints = {520, 615, 580, 615};
        pointPaint.setStrokeCap(Paint.Cap.ROUND);
        pointPaint.setStrokeWidth(20);
        canvas.drawPoints(eyePoints, 0, 4, pointPaint);

3. 拿什么绘制?

只有画布还不够,要呈现效果,我们还需要一支画笔,就是我们的Paint类,负责绘制的风格和样式。

paint的官方api地址(科学上网哦):https://developer.android.com/reference/android/graphics/Paint.html

基本样式设置:

API说明备注
setStyle(Paint.Style style)设置风格是边框型还是填充型枚举值:FILL、STROKE、FILL_AND_STROKE
setStrokeWidth(float width)设置边框大小   

setColor(long color)

setColor(int color)

setARGB(int a, int r, int g, int b)

设置颜色 
setShader(Shader shader)设置渐变色系 线性渐变、辐射渐变、扫描渐变等 
setAntiAlias(boolean aa)设置抗锯齿

还可以在Paint的构造方法中设置抗锯齿

new Paint(Paint.ANTI_ALIAS_FLAG)
setStrokeCap(Paint.Cap cap)设置线头形状

枚举值:BUTT、ROUND、SQUARE

 

 

 

 

 

 

 

 

 

 

 

setStrokeCap(Paint.Cap cap):

PorterDuff.Mode:

在paint或canvas方法参数中有PorterDuff.Mode类型的参数,它是用来指定两个图像共同绘制时的颜色策略的,引用官方对16种枚举值的说明,其中src为源图像,dst为目标图像,具体可以参见https://www.jianshu.com/p/0edabe6ce8c9

一般默认是SrcOver模式,按后绘制的遮盖先绘制的正常绘制顺序执行

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值