【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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月23日 16时37分07秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Filter
2019-04-29
微服务架构实施原理详解
2019-04-29
必须了解的mysql三大日志-binlog、redo log和undo log
2019-04-29
局部敏感哈希Locality Sensitive Hashing归总
2019-04-30
图像检索中为什么仍用BOW和LSH
2019-04-30
图˙谱˙马尔可夫过程˙聚类结构----by林达华
2019-04-30
深度学习读书笔记之AE(自动编码AutoEncoder)
2019-04-30
深度学习读书笔记之RBM
2019-04-30
深度学习word2vec笔记之基础篇
2019-04-30
法国INRIA Data Sets & Images 数据集和图像库
2019-04-30
训练自己haar-like特征分类器并识别物体(1)
2019-04-30
iOS容易造成循环引用的三种场景,就在你我身边!
2019-04-30
有一个会做饭的女友是一种怎样的体验?
2019-04-30
Storm入门之第一章
2019-04-30
java提高篇之数组(1):认识JAVA数组
2019-04-30
java提高篇之数组(2)
2019-04-30
浅析数据一致性
2019-04-30
Java 多维数组遍历
2019-04-30