关于android:Android-自定义View-Canvas绘制几何图形基础

37次阅读

共计 7510 个字符,预计需要花费 19 分钟才能阅读完成。

我的项目需要:本我的项目中为本人的毕设我的项目,其中有一个模块须要通过 APP 进行码垛设计,并将码垛的后果发送给机械手的控制器。该模块的需要具体如下:

1. 能够从物料库中拖动我的项目的物料模块到码盘。2. 用户将对应的图形模块在码盘上进行排列组合,APP 将最终确定的组合的各图形的坐标进行保留
3. 能够减少码垛层数
4. 能够自定义生成不同大小的图形

现有的 Android 组件无奈满足这一需要,在 Android 中只能进行自定义 View 设计。于是开展了对自定义 View 的学习。

自定义 View 的流程

  1. 构造函数 View 初始化
  2. onMeasure 测量 View 大小
  3. onSizeChanged 确定 View 大小
  4. onLayout 确定子 View 布局地位
  5. onDraw 理论绘制内容
  6. 提供接口 监听 View 状态

1 Android Graphics 图形库

作为 android 的图形库提供了以下几个类

  1. Drawable

      通用的图形对象,用于装载罕用格局的图像,能够是 PNG,JPG 这样的图像,也能够是后面学的 13 种 Drawable 类型的可视化对象.  
      能够了解为放画用的 --- 画框
  2. 位图:Bitmap 来放弃(hold)那些像素

      能够简略的了解为 画架
      先把画放到下面,而后能够进行一些解决,比方获取图像文件信息,做旋转切割,放大放大等操作
  3. 画布:Canvas 来响应画画(draw)的调用(并将其写入 bitmap)

      就是能够下面作画(绘制),能够用 Paint(画笔),来画各种形态或者写字,又能够用 Path(门路) 来绘制多个点,而后连接成各种图形
    
  4. 画笔:paint 形容画画的色彩和款式等
  5. Matrix(矩阵)

      用于图形特效解决的,色彩矩阵(ColorMatrix),还有应用 Matrix 进行图像的平移,缩放,旋转,歪斜等“颜料“:drawing primitive,比方矩形、门路、文字、位图等其余元素
    

!!! Canvas(画布),Paint(画笔),Path(门路) 是 android.graphics 接口类下的三个绘图 API


1.1 Paint 画笔

Paint (画笔) 用于设置绘制格调, 如 线宽(笔触粗细), 色彩, 透明度和填充格调

取得一个 Paint 对象实例很简略

Paint paint = new Paint();

图形的形态由 Canvas 确定 当绘制进去的色彩成果由画笔 Paint 确定

mPaint.setStyle(Paint.Style.FILL);  // 设置画笔模式为填充

画笔有三种模式 
STROKE                // 描边
FILL                  // 填充
FILL_AND_STROKE       // 描边加填充
办法 阐明
setARGB(int a,int r,int g,int b) 设置绘制的色彩,a 代表透明度,r,g,b 代表色彩值
setAlpha(int a) 设置绘制图形的透明度
setColor(int color) 设置绘制的色彩,应用色彩值来示意,该色彩值包含透明度和 RGB 色彩。
setAntiAlias(boolean aa) 设置是否应用抗锯齿性能,会耗费较大资源,绘制图形速度会变慢
setDither(boolean dither) 设定是否应用图像抖动解决,会使绘制进去的图片色彩更加平滑和丰满,图像更加清晰
setFilterBitmap(boolean filter) 如果该项设置为 true,则图像在动画进行中会滤掉对 Bitmap 图像的优化操作,放慢显示速度,本设置项依赖于 dither 和 xfermode 的设置
setMaskFilter(MaskFilter maskfilter) 设置 MaskFilter,能够用不同的 MaskFilter 实现滤镜的成果,如滤化,平面等
setColorFilter(ColorFilter colorfilter) 设置色彩过滤器,能够在绘制色彩时实现不必色彩的变换成果
setPathEffect(PathEffect effect) 设置绘制门路的成果,如点画线等
setShader(Shader shader) 设置图像成果,应用 Shader 能够绘制出各种突变成果
setShadowLayer(float radius ,float dx,float dy,int color) 在图形上面设置暗影层,产生暗影成果,radius 为暗影的角度,dx 和 dy 为暗影在 x 轴和 y 轴上的间隔,color 为暗影的色彩
setStyle(Paint.Style style) 设置画笔的款式,为 FILL,FILL_OR_STROKE,或 STROKE
setStrokeCap(Paint.Cap cap) 当画笔款式为 STROKE 或 FILL_OR_STROKE 时,设置笔刷的图形款式,如圆形样 Cap.ROUND, 或方形款式 Cap.SQUARE
setSrokeJoin(Paint.Join join) 设置绘制时各图形的联合形式,如平滑成果等
setStrokeWidth(float width) 当画笔款式为 STROKE 或 FILL_OR_STROKE 时,设置笔刷的粗细度
setXfermode(Xfermode xfermode) 设置图形重叠时的解决形式,如合并,取交加或并集,常常用来制作橡皮的擦除成果
setFakeBoldText(boolean fakeBoldText) 模仿实现粗体文字,设置在小字体上成果会十分差
setSubpixelText(boolean subpixelText) 设置该项为 true,将有助于文本在 LCD 屏幕上的显示成果
setTextAlign(Paint.Align align) 设置绘制文字的对齐方向
setTextScaleX(float scaleX) 设置绘制文字 x 轴的缩放比例,能够实现文字的拉伸的成果
setTextSize(float textSize) 设置绘制文字的字号大小
setTextSkewX(float skewX) 设置斜体文字,skewX 为歪斜弧度
setTypeface(Typeface typeface) 设置 Typeface 对象,即字体格调,包含粗体,斜体以及衬线体,非衬线体等
setUnderlineText(boolean underlineText) 设置带有下划线的文字效果
setStrikeThruText(boolean strikeThruText) 设置带有删除线的成果
setStrokeJoin(Paint.Join join) 设置结合处的样子 Miter: 结合处为锐角 Round: 结合处为圆弧 BEVEL: 结合处为直线
setStrokeMiter(float miter) 设置画笔倾斜度
setStrokeCap(Paint.Cap cap) 设置转弯处的格调
float ascent() 测量 baseline 之上至字符最高处的间隔)
float descent() baseline 之下至字符最低处的间隔
int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth) 检测一行显示多少文字
clearShadowLayer() 革除暗影层

1.2 Path 门路

Path(门路) 简略点说就是描点,连线

创立了 Path 的实例后,能够调用 Canvas 的 drawPath(path,paint) 将图形绘制进去

Path (门路) 的罕用办法如下

办法 阐明
addArc(RectF oval, float startAngle, float sweepAngle 为门路增加一个多边形
addCircle(float x, float y, float radius, Path.Direction dir) 给 Path 增加圆圈
addOval(RectF oval, Path.Direction dir) 增加椭圆形
addRect(RectF rect, Path.Direction dir) 增加一个区域
addRoundRect(RectF rect, float[] radii, Path.Direction dir) 增加一个圆角区域
isEmpty() 判断门路是否为空
transform(Matrix matrix) 矩阵变换
transform(Matrix matrix, Path dst) 矩阵变换并将后果存到门路

更高级的成果能够应用 PathEffect 类,罕用办法如下

办法 阐明
moveTo(float x, float y) 不会进行绘制,只用于挪动挪动画笔
lineTo(float x, float y) 用于直线绘制,默认从 (0,0) 开始绘制,用 moveTo 挪动。比方 mPath.lineTo(300, 300);canvas.drawPath(mPath, mPaint);
quadTo(float x1, float y1, float x2, float y2) 用于绘制圆滑曲线,即贝塞尔曲线,同样能够联合 moveTo 应用
rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 同样是用来实现贝塞尔曲线的。(x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为完结点
arcTo(RectF oval, float startAngle, float sweepAngle) 绘制弧线(理论是截取圆或椭圆的一部分)ovalRectF 为椭圆的矩形,startAngle 为开始角度,sweepAngle 为完结角度

1.3 Canvas 画布

android.graphics.Canvas 类提供了很多“画“的办法,让这块画布具备了丰富多彩的画画能力。比方:画点、线、矩形、椭圆、圆、文字等等。上面的例子演示了这些办法的应用。

创立 Canvas 画布的办法

  • 创立有一个空的画布,能够应用 setBitmap() 办法来设置绘制具体的画布
Canvas c = Canvas();
  • 以 bitmap 对象创立一个画布,将内容都绘制在 bitmap 上 bitmap 不能 null
Canvas c = Canvas(Bitmap bitmap);

绘制办法

  1. drawXXX()办法族 ::以肯定的坐标值在以后画图区域画图,另外图层会叠加,即前面绘画的图层会笼罩后面绘画的图层
办法 阐明
drawRect(RectF rect, Paint paint) 绘制区域,参数一为 RectF 一个区域
drawPath(Path path, Paint paint) 绘制一个门路,参数一为 Path 门路对象
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) 贴图,参数一就是咱们惯例的 Bitmap 对象,参数二是源区域(这里是 bitmap),参数三是指标区域(应该在 canvas 的地位和大小),参数四是 Paint 画刷对象,因为用到了缩放和拉伸的可能,当原始 Rect 不等于指标 Rect 时性能将会有大幅损失
drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) 画线,参数一起始点的 x 轴地位,参数二起始点的 y 轴地位,参数三起点的 x 轴程度地位,参数四 y 轴垂直地位,最初一个参数为 Paint 画刷对象。
drawPoint(float x, float y, Paint paint) 画点,参数一程度 x 轴,参数二垂直 y 轴,第三个参数为 Paint 对象
drawText(String text, float x, floaty, Paint paint) 渲染文本,Canvas 类除了下面的还能够描述文字,参数一是 String 类型的文本,参数二 x 轴,参数三 y 轴,参数四是 Paint 对象。
drawOval(RectF oval, Paint paint) 画椭圆,参数一是扫描区域,参数二为 paint 对象;
drawCircle(float cx, float cy, float radius,Paint paint) 绘制圆,参数一是中心点的 x 轴,参数二是中心点的 y 轴,参数三是半径,参数四是 paint 对象;
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 画弧,参数一是 RectF 对象,一个矩形区域椭圆形的界线用于定义在形态、大小、电弧,参数二是起始角 (度) 在电弧的开始,参数三扫描角 (度) 开始顺时针测量的,参数四是如果这是真的话, 包含椭圆核心的电弧, 并敞开它, 如果它是假这将是一个弧线, 参数五是 Paint 对象;
drawColor() 绘制色彩
  1. clipXXX() 办法族: 在以后的画图区域裁剪 (clip)出一个新的画图区域,这个画图区域就是 canvas 对象的以后画图区域了
    比方:clipRect(new Rect()),那么该矩形区域就是 canvas 的以后画图区域
  2. save() 和 restore() 办法
办法 阐明
save() 用来保留 Canvas 的状态。save 之后,能够调用 Canvas 的平移、放缩、旋转、错切、裁剪等操作
restore() 用来复原 Canvas 之前保留的状态。避免 save 后对 Canvas 执行的操作对后续的绘制有影响

!!!留神
save() 和 restore() 要配对应用(restore 能够比 save 少, 但不能多),若 restore 调用次数比 save 多, 会报错

  1. getXXX 办法族 获取 Canvas 相干的一些值
  2. translate() 平移
translate(float dx, float dy)  

平移就是将画布的坐标原点向左右方向挪动 x,向高低方向挪动 y

canvas 默认坐标原点地位为左上角 (0,0)

参数 阐明
dx 为程度方向的挪动间隔
dy 为垂直方向的挪动间隔
  1. scale 缩放
void scale(float sx, float sy)
final void scale(float sx, float sy, float px, float py)

对画布进行缩放

参数阐明

参数 阐明
sx 程度方向缩放比例,小于 1 为放大,大于 1 为放大
sy 竖直方向的缩放比例,小于 1 为放大,大于 1 为放大
px 指定旋转的中心点坐标的 x 坐标
py 指定旋转的中心点坐标的 y 坐标
  1. rotate(float degrees) 旋转,angle 指旋转的角度,顺时针旋转
void rotate(float degrees)
final void rotate(float degrees, float px, float py)

围绕坐标原点或指定坐标旋转 degrees 度,值为正顺时针

参数阐明

参数 阐明
degrees 旋转角度
px 指定旋转的中心点坐标的 x 坐标
py 指定旋转的中心点坐标的 y 坐标
  1. skew 歪斜
skew(float sx, float sy)

歪斜肯定的角度

参数阐明

参数 阐明
sx 为 x 轴方向上歪斜的对应角度,tan(角度)
sy 为 y 轴方向上歪斜的对应角度,tan(角度)

两个参数都是 tan 值,比方要在 x 轴方向上歪斜 60 度,那么 sx 为

tan(60) = 根号 3 = 1.732

Canvas 坐标系

Canvas 以左上角为原点,向右为 X 轴正方向,向下为 Y 轴正方向

Layer 图层

画布 Canvas 给开发者提供了 Layer 反对。Layer 是依照栈构造进行治理。

当开发者带哦用 Save 办法时候,会保留以后 Canvas 的状态作为一个 Layer 增加到 Canvas 栈。

而当咱们调用 restore() 办法的时候,会复原之前 Canvas 的状态,而此时 Canvas 的图层栈 会弹出栈顶的那个 Layer,后继的 Layer 来到栈顶,此时的 Canvas 回复到此栈顶时保留的 Canvas 状态

简略说就是 save()往栈压入一个 Layer,restore()弹出栈顶的一个 Layer,这个 Layer 代表 Canvas 的 状态!也就是说能够 save() 屡次,也能够 restore() 屡次,然而 restore() 的调用次数 不能大于 ** save()否则会引发谬误

OnDraw

创立画笔

绘制常见的几何图形实例

绘制点

    drawPoint(float x, float y, Paint paint) // 画点,参数一程度 x 轴,参数二垂直 y 轴,第三个参数为 Paint 对象。

绘制直线

绘制直线须要两个点,初始点和完结点,同样绘制直线也能够绘制一条或者绘制一组:

canvas.drawLine(300,300,500,600,mPaint);    // 在坐标 (300,300)(500,600) 之间绘制一条直线
canvas.drawLines(new float[]{// 绘制一组线 每四数字 (两个点的坐标) 确定一条线
    100,200,200,200,
    100,300,200,300
},mPaint);

绘制矩形

确定一个矩形个别须要四个数据:对角线的两个点的坐标值。通常咱们次啊用左上角和右下角的两个点的坐标值

对于绘制矩形,Canvas 提供了三种重载办法,第一种就是提供四个数值 (矩形左上角和右下角两个点的坐标) 来确定一个矩形进行绘制。其余两种是先将矩形封装为 Rect 或 RectF(实际上依然是用两个坐标点来确定的矩形),而后传递给 Canvas 绘制,如下:

// 第一种
canvas.drawRect(100,100,800,400,mPaint);

// 第二种
Rect rect = new Rect(100,100,800,400);
canvas.drawRect(rect,mPaint);

// 第三种
RectF rectF = new RectF(100,100,800,400);
canvas.drawRect(rectF,mPaint)

绘制圆角矩形

// 第一种
RectF rectF = new RectF(100,100,800,400);
canvas.drawRoundRect(rectF,30,30,mPaint);

// 第二种
canvas.drawRoundRect(100,100,800,400,30,30,mPaint);

绘制圆

canvas.drawCircle(500,500,400,mPaint);  // 绘制一个圆心坐标在(500,500),半径为 400 的圆。

绘制椭圆

    drawCircle(float cx,float cy,float radius,Paint paint)
    // 绘制圆,参数一是中心点的 x 轴,参数二是中心点的 y 轴,参数三是半径,参数四是 paint 对象;

绘制圆弧

    drawArc(RectF oval,float startAngle,float sweepAngle,boolean useCenter,Paint paint)
    // 画弧
    参数一是 RectF 对象,一个矩形区域椭圆形的界线用于定义在形态、大小、电弧,参数二是起始角 (度) 在电弧的开始,参数三扫描角 (度) 开始顺时针测量的,参数四是如果这是真的话, 包含椭圆核心的电弧, 并敞开它

参考文档

  1. Canvas
  2. Paint
  3. Path

正文完
 0