Android--Canvas

draw系列

canvas.drawArc

1.方法

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

2.案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        RectF recf = new RectF(120,120,300,300);
        canvas.drawRect(recf,paint2);
        /**
         * recf 中心为坐标中心
         * startAngle,负数或大于360则对360模除。
         * sweepAngle,大于360,则画出一圈。
         * userCenter 若为true表示此弧会和 RectF 中心相连形成扇形,否则,弧的两头直接相连形成图形。
         * mPaint 画笔
         */
        canvas.drawArc(recf,0,150,true,mPaint);
    }

canvas.drawCircle

1.方法

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

2.案例

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        /**
         * cx cy 所画圆的中心位置
         * radius 所画圆的半径
         * mPaint 画笔
         */
        canvas.drawCircle(100,100,80,mPaint);
    }

canvas.drawBitmap

1.方法1

/**
 * bitmap 要画在画布上的位图
 * matrix 构建的矩阵作用于将要画出的位图
 */
drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) 

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        Matrix matrix = new Matrix();
        matrix.postTranslate(400,0);//左移400
        matrix.postRotate(10);//顺时针旋转10
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.mv),matrix,mPaint);
    }

2.方法2

/**
 * src 可为null 表示画整个位图,否则只画出位图的一块矩形区域图
 * dst 定义的一个矩形范围,位图会平移或缩放来将自身放入矩形内
 */
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        Rect rect = new Rect(100,10,200,110);//取bitmap上src区域部分图像
        Rect dst = new Rect(100,100,500,500);//绘制的最终区域,一定填满
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.mv),rect,dst,mPaint);
    }

3.方法3

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

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.mv),200,200,mPaint);
    }

4.方法4

drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint) 

canvas.drawColor,drawRGB

画整个画布的背景

canvas.drawLine(s)

1.方法1

/**
 * 前四个参数为直线的起点和终点的XY轴坐标
 */
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(64);
        canvas.drawText("起点(20,100)",22,100,mPaint);
        canvas.drawText("终点(250,200)",252,200,mPaint);
        canvas.drawLine(20,100,250,200,mPaint);
    }

2.方法2

drawLines(float[] ps,Paint paint)

案例

@SuppressLint("Range")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(64);
        canvas.drawText("A(20,100)",22,100,mPaint);
        canvas.drawText("B(250,200)",252,200,mPaint);
        canvas.drawText("C(20,300)",22,300,mPaint);
        canvas.drawText("D(250,400)",252,400,mPaint);
        canvas.drawLines(new float[]{20,100,250,200,250,200,20,300,20,300,250,400},mPaint);
    }

3.方法3

/**
 *pts:待画的坐标点数组,格式为(x1,y1,x2,y2,...),至少4个值
 *offset:要跳过坐标点数组中几个值才开始画(必须是4的倍数)
 *count:至少为2,offset 之后数组的大小
 */
drawLines(float[] pts, int offset, int count, Paint paint)  

案例

@SuppressLint("Range")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(64);
        canvas.drawText("A(20,100)",22,100,mPaint);
        canvas.drawText("B(250,200)",252,200,mPaint);
        canvas.drawText("C(20,300)",22,300,mPaint);
        canvas.drawText("D(250,400)",252,400,mPaint);
        canvas.drawLines(new float[]{20,100,250,200,250,200,20,300,20,300,250,400},4,8,mPaint);
    }

canvas.drawRect

1.方法

/**
 * 确定矩形四个顶点的位置配上画笔即可
 */
void drawRect(float left, float top, float right, float bottom, Paint paint)

void drawRect(Rect r, Paint paint) 

void drawRect(RectF r, Paint paint)  

canvas.drawOval

drawOval(RectF oval,Paint paint)

drawOval(float left, float top, float right, float bottom, Paint paint)

canvas.drawPaint

方法

/**
 *自定义paint 画在整个画布上
 */
drawPaint(Paint paint) 

canvas.drawPoint(s)

/**
 *类似drawLine(s) 可以参考
 */
drawPoint(float x, float y,Paint paint)

drawPoints(float[] pts, Paint paint)

drawPoints(float[] pts, int offset, int count,Paint paint)

canvas.drawRoundRect

/**
 *  rx,ry 表示 left 到 left+rx 与 left 到 left+ry 所围区域做弧,其余三个角类似,当 rx=ry>=(right-left)/2 时表示画一个半径为 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)  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        canvas.drawRoundRect(new RectF(100,200,400,400),50,50,mPaint);
    }

canvas.drawText

1.方法1

/**
 * x,y位置开始画text 注意 其中y 是表示文字的基线(baseLine)
 */
drawText(String text,float x,float y,Paint paint)

案例

String text = "涂文远TWYtwy abcd";
int centery = 300;
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setTextSize(100);
mPaint.setColor(Color.RED);
 
paint2.reset();
paint2.setColor(Color.GREEN);
paint2.setAntiAlias(true);
canvas.drawLine(0,centery,1000,centery,paint2);//中心线
 
Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
int baseliney = centery+(fontMetricsInt.bottom-fontMetricsInt.top)/2-fontMetricsInt.bottom;
canvas.drawLine(0,baseliney,1000,baseliney,paint2);//基线

2.方法2

/**
 * 画出start 到 end(不含end)之间的字符
 */ 
drawText(CharSequence text, int start, int end, float x, float y, Paint paint)  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(32);
        canvas.drawText("abcdefg",3,6,50,300,mPaint);
    }

3.方法3

/*
 * text 字符数组的定义
 * index 表示从第几个字符开始
 * count 表示截取数组的长度
 */
drawText(char[] text, int index, int count, float x, float y, Paint paint)  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(64);
        canvas.drawText("abcdefg".toCharArray(),3,2,50,300,mPaint);
    }

4.方法4

/**
 * path文字绘制的路径
 * hOffset 相对于路径的水平偏移量
 * vOffset 相对于路径垂直偏移量
 */
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(32);
        Path path = new Path();
        path.addCircle(100,100,50,Path.Direction.CCW);
        canvas.drawPath(path,paint2);
        canvas.drawTextOnPath("abcdef",path,0,0,mPaint);
    }

5.方法5

/**
 * text 字符数组的定义
 * index 表示从第几个开始
 * count 表示截取数组的长度
 * path 路径
 */
drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)  

6.方法6

/**
 * contextStart:可选,直接=start
 * contextEnd:可选,直接=end
 * x,y:文字绘制起点
 * isRt1(isRightToLeft):文字是否支持rtl
 */
drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint paint)  

drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, boolean isRtl, Paint paint)  

案例

@RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(32);
        canvas.drawTextRun("abcdefg".toCharArray(),2,3,2,3,50,300,true,mPaint);
    }

canvas.drawPath

/**
 * 根据定义的路径画出图
 */
drawPath(Path path, Paint paint) 

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(32);
        Path path = new Path();
        path.addCircle(300,300,150,Path.Direction.CW);
        canvas.drawPath(path,mPaint);
    }

canvas.clipxxx系列

canvas.clipPath

1.方法1

/**
 * 按所定义的路线剪裁,默认Region.Op.INTERSECT表示剪裁出相交的部分
 */
clipPath(Path path)  

/**
 * 用指定的路径 path 修改当前的剪裁对op参数的理解:以剪裁两次的区域分别为A,B来区别
 * Region.Op.DIFFERENCE:剪裁出差异的部分,类似 A-B 部分
 * Region.Op.REPLACE:后剪裁B的覆盖剪裁的A
 * Region.Op.REVERSE_DEFFERENCE:剪裁出差异的部分,类似 B-A 部分
 * Region.Op.INTERSECT:剪裁出相交的部分,类似 A交B 部分
 * Region.Op.UNION:剪裁出AB合并的部分,类似** AUB**
 * Region.Op.XOR:是** (AUB)-(A交B)** 刚好与** A交B** 相对
 */
clipPath(Path path, Region.Op op)  

clipRect(Rect rect)  

clipRect(Rect[F] rect, Region.Op op)//[]表示可选  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        canvas.drawColor(Color.BLUE);
        canvas.drawRect(new RectF(20, 20, 120, 120), mPaint);
        canvas.drawCircle(120, 70, 50, mPaint);
        canvas.clipRect(new RectF(20, 20, 120, 120));
        Path path = new Path();
        path.addCircle(120, 70, 50, Path.Direction.CCW);
        canvas.clipPath(path, op);
        canvas.drawColor(Color.GREEN);
        Toast.makeText(getContext(),op.name(),Toast.LENGTH_LONG).show();
    }

案例

canvas的保存与恢复

  1. 解释:用来保存或恢复 Canvas 的状态
  2. 作用:save 之后可以调用 Canvas 的平移、放缩、旋转、错切、裁剪等对当前画布进行操作,再进行相应的绘制,避免影响画布上已绘制的 view,配合 canvas.restore()(将当前画布恢复到初始状态) 使用

canvas的变幻操作

canvas.translate

/**
 * 作用 移动当前画布水平距离dx 垂直距离dy
 */
canvas.translate(float dx,float dy)

案例

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        canvas.drawColor(Color.BLUE);
        canvas.translate(100,100);
        canvas.drawCircle(0,0,50,mPaint);
    }

canvas.scale

1.方法1

/**
 * 作用:sx、sy 是 x、y 方向上缩放的倍数,画布缩放后,再画出的图片相应的坐标都会进行缩放
 */
canvas.scale(float sx, float sy)  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        canvas.drawColor(Color.BLUE);
        canvas.save();
        canvas.scale(0.5f,0.5f);//x,y均缩小一半
        canvas.drawCircle(100,100,50,mPaint);
        canvas.restore();
        mPaint.setColor(Color.WHITE);
        canvas.drawCircle(100,100,50,mPaint);
    }

2.方法2

/**
 * 缩放画布并平移画布到基准点 (px,py)  px,py 为缩放后画布新的坐标原点(也叫缩放基准点)
 */
canvas.scale (float sx, float sy, float px, float py)  

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        canvas.drawColor(Color.BLUE);
        mPaint.setColor(Color.WHITE);
        canvas.drawCircle(100,100,50,mPaint);
        canvas.save();
        canvas.scale(0.5f,0.5f,100,100);
        mPaint.setColor(Color.RED);
        canvas.drawCircle(100,100,50,mPaint);
        canvas.restore();
    }

canvas.rotate

canvas.rotate(float degrees)
/**
 * degrees 顺时针旋转角度 dx dy 基准点坐标
 */
canvas.rotate(float degrees,float dx,float dy)

案例

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        canvas.drawColor(Color.BLUE);
        mPaint.setColor(Color.WHITE);
        canvas.drawRect(new RectF(80,80,180,180),mPaint);
        canvas.save();
        //canvas.rotate(45);
        canvas.rotate(45,200,200);
        mPaint.setColor(Color.RED);
        canvas.drawRect(new RectF(80,80,180,180),mPaint);
        canvas.restore();
    }

 

本文参考 https://www.jianshu.com/p/afa06f716ca6 感谢该作者

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值