【5年Android从零复盘系列之十】Android自定义View(5):画布Canvas详解(图文)
发布日期:2021-06-29 18:17:41 浏览次数:3 分类:技术文章

本文共 8074 字,大约阅读时间需要 26 分钟。

1.简介

Android系统提供Canvas、Paint 、Path三剑客用于绘制View图形。

如果将自定义View的绘制看作美术课绘画作业的话,

Canvas可视为画板上的空白画布,

Paint可视为画笔,

Path可视为绘画者的执笔路径。

其他坐标系等基础,可参考阅读:

2.Canvas 的常用功能

方法 功能
drawColor() 设置画布颜色
drawCircle() 绘制圆形
drawRect() 绘制矩形
drawRoundRect() 绘制带圆角的矩形
drawArc() 绘制扇形 or 弧线
drawPoint() 绘制点
drawPoints() 绘制多个点
drawLine() 绘制线
drawLines() 绘制多条线
drawOval 绘制椭圆
drawPath() 按预设画笔路径,绘制 对应得图形
drawBitmap() 在指定位置,绘制Bitmap对象
drawText() 绘制文字
clipPath() 根据自定义图形裁剪
clipRect() 按矩形裁剪

3. 使用

3.1 drawColor() & drawCircle()

package com.cupster.base_super_resource;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.View;import androidx.annotation.Nullable;public class CanvasView extends View {
Paint mPaint; Path mPath ; private void initSetting(){
mPaint = new Paint(); mPath = new Path(); } @Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 0. onDraw可能多次调用,每次绘制前都先复原paint&path mPaint.reset(); mPath.reset(); //1. 设置画布底色// canvas.drawColor(Color.RED);// canvas.drawColor(getResources().getColor(R.color.colorAccent));//使用xml定义的全局颜色 canvas.drawColor(Color.parseColor("#e5f7ff"));//使用自定义颜色// canvas.drawRGB(255 ,0 ,0 );//rgb// canvas.drawARGB(127 ,255 ,0 ,0 );//argb //2. 绘制圆 mPaint.setColor(Color.parseColor("#ff8696")); // 参数1 圆心x ; 参数2 圆心y ; 参数3 半径r ; canvas.drawCircle(200 ,200,120 ,mPaint);//java代码中直接使用的绘制单位是px,xml中使用的是dp } public CanvasView(Context context) {
super(context); initSetting(); } public CanvasView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); initSetting(); } public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); initSetting(); } public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); initSetting(); }}

布局文件中使用

3.2 DrawRect()

public class CanvasView extends View {
Paint mPaint; Path mPath ; private void initSetting(){
mPaint = new Paint(); mPath = new Path(); } @Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 0. onDraw可能多次调用,每次绘制前都先复原paint&path mPaint.reset(); mPath.reset(); canvas.drawColor(Color.parseColor("#e5f7ff"));//使用自定义颜色 //3. 绘制矩形 mPaint.setColor(Color.parseColor("#ff8696")); //参数1:矩形【左】上角坐标x;参数2:矩形【左】上角坐标y; 参数3:矩形【右】下角坐标x ;参数4:矩形【右】下角坐标y canvas.drawRect(50 ,50 ,150 ,250 ,mPaint);// canvas.drawRect(new Rect(50 ,50 ,250 ,250 ),mPaint);//效果同上 //4. 绘制圆角矩形// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// canvas.drawRoundRect(100, 100, 350, 220, 50, 50, mPaint);// } } public CanvasView(Context context) {
super(context); initSetting(); } public CanvasView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); initSetting(); }

3.3 drawPoint() & drawPoints()

@Override    protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 0. onDraw可能多次调用,每次绘制前都先复原paint&path mPaint.reset(); mPath.reset(); canvas.drawColor(Color.parseColor("#e5f7ff"));//使用自定义颜色 mPaint.setColor(Color.parseColor("#ff8696")); //. 绘制原点:点形状 大小由 paint决定 mPaint.setStrokeWidth(20);//画笔宽度 mPaint.setAntiAlias(true);//抗锯齿效果 mPaint.setStyle(Paint.Style.STROKE);//描边 mPaint.setStrokeCap(Paint.Cap.ROUND);//设置线头的模式 canvas.drawPoint( 80 ,80,mPaint);//圆心坐标x,y //绘制多个圆点// float[] points = {10, 10, 35, 35, 30, 80, 80, 30, 80, 80, 120, 60};// canvas.drawPoints(points , 2 ,points.length-2 ,mPaint);//画部分点:p1:点集合,两个一组;p2:跳过几个集合参数;p3:使用多少个集合参数;p4:画笔// canvas.drawPoints(points ,mPaint);//全画 }

3.4 drawOval()

@Override    protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 0. onDraw可能多次调用,每次绘制前都先复原paint&path mPaint.reset(); mPath.reset(); canvas.drawColor(Color.parseColor("#e5f7ff"));//使用自定义颜色 mPaint.setColor(Color.parseColor("#ff8696")); //6. 绘制椭圆 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//参数1:椭圆对应矩形【左】上角坐标x;参数2:椭圆对应矩形【左】上角坐标y; 参数3:椭圆对应矩形【右】下角坐标x ;参数4:椭圆对应矩形【右】下角坐标y canvas.drawOval(30,30 ,220 ,120,mPaint); }

3.5 drawLine() & drawLines()

@Override    protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 0. onDraw可能多次调用,每次绘制前都先复原paint&path mPaint.reset(); mPath.reset(); canvas.drawColor(Color.parseColor("#e5f7ff"));//使用自定义颜色 mPaint.setColor(Color.parseColor("#ff8696")); //7. 画线 mPaint.setStrokeWidth(6); //4个参数值对应的是两端点的坐标 //canvas.drawLine(30,30,120,120,mPaint); float[] points = {
10, 10, 35, 35, 35, 35, 80, 30, 80, 30, 120, 60};// canvas.drawLines(points ,4 ,points.length -4 ,mPaint); canvas.drawLines(points ,mPaint);

3.6 绘制弧线 & 扇形

@Override    protected void onDraw(Canvas canvas) {
super.onDraw(canvas); mPaint.reset(); mPath.reset(); canvas.drawColor(Color.parseColor("#e5f7ff")); mPaint.setColor(Color.parseColor("#000000")); //8. 画弧线/扇形 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//前4个参数: 所依据的椭圆(圆)对应的矩形--的 左上角顶点坐标 & 右下角顶点坐标 //第5个参数 startAngle:起始角度,x轴方向为0度,【特殊】【顺时针为正角度】 //第6个参数 sweepAngle:扫过的角度,【特殊】【顺时针为正角度】 //第7个参数 useCenter:是否连接到圆心,true对应连接-扇形 ,false对应不连-弧线 canvas.drawArc(30, 30, 200, 200, -90, 90, true, mPaint); // 绘制扇形 mPaint.setStyle(Paint.Style.STROKE);//画弧线需设置描边、不填充 canvas.drawArc(30, 30, 200, 200, 90, 90, false, mPaint); // 绘制弧线 } }

3.7 绘制path

@Override    protected void onDraw(Canvas canvas) {
super.onDraw(canvas); mPaint.reset(); mPath.reset(); //画坐标轴 mPaint.setColor(Color.parseColor("#101010")); mPaint.setStyle(Paint.Style.STROKE); mPath.moveTo(120, 120);//y轴顶点(120,120) mPath.rLineTo(0, 200);//y轴方向 path移动量 mPath.rLineTo(200, 0);//x轴方向 path移动量 canvas.drawPath(mPath, mPaint);//绘制}

3.8 裁剪canvas.clipXxx & canvas.clipOutXxx

canvas.save();        canvas.clipRect(0,0,128,128);//裁剪 显示区域        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_fangzi);        canvas.drawBitmap(bitmap                ,64 ,64//原bitmap绘制起点坐标                ,mPaint);        canvas.restore();
canvas.save();        canvas.clipOutRect(0,0,128,128);//裁剪 显示区域        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_fangzi);        canvas.drawBitmap(bitmap                ,64 ,64//原bitmap绘制起点坐标                ,mPaint);        canvas.restore();

3.9 canvas变换

canvas.save();//        canvas.rotate(15 );//绕 (0,0)        canvas.rotate(-90 ,130,130);// 绕指定点 【特殊】【顺时针为正值角度】        canvas.translate( -20 ,0);        canvas.scale(1.5f ,1.0f , 130 ,130 );//x缩放倍数 y缩放倍数 ,缩放原点x ,缩放原点y        canvas.skew( 0.0f ,0.5f);//错切  倾斜值        canvas.drawBitmap(BitmapFactory.decodeResource(getResources() ,R.mipmap.ic_fangzi)                ,130 ,130//绘制起点坐标                ,mPaint);        canvas.restore();

3.10 matrix自定义变换

//1.创建Matrix对象        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_fangzi);        Matrix matrix = new Matrix();        matrix.reset();        //2.几何变换        matrix.postTranslate(0,10);        matrix.postRotate(45,130,130);        matrix.postScale(1.3f,1.3f,130,130);        matrix.postSkew(0,0.3f);        canvas.save();        //3.把几何变换应用到Canvas中        canvas.concat(matrix);        canvas.drawBitmap(bitmap,130,130,mPaint);        canvas.restore();

转载地址:https://cupster.blog.csdn.net/article/details/112484294 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【5年Android从零复盘系列之十一】Android自定义View(6):画笔Paint
下一篇:【5年Android从零复盘系列之九】Android自定义View(4):自绘式详解(图文)

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月23日 16时37分07秒