在上一篇总结中,我们介绍了一些自定义View的基础知识。在本章中我们继续介绍Canvas和Pinat的基本概念。
目录
一、简介
Canvas直译过来为画布的意思,用于完成在View上的绘图,Bitmap提供内存,绘的画会保存在Bitmap中。它是安卓平台2D图形绘制的基础,非常强大。
Paint相当于画笔的意思,Canvas负责进行绘制各种各样的图形,而Paint则主要负责设置绘图的风格,包括画笔的颜色,粗细,填充风格等。
二、详解
1、Canvas
官方文档中关于Canvas的解释:
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).
Canvas 是画布,来响应绘画(Draw)的调用(并将其写入Btmap)。想要画出一些东西需要4个基本要素:
- 保存像素的Bitmap(相当于纸张)
- 管理绘制调用的Canvas(相当于打印机)
- 拥有颜色和风格信息的画笔(相当于墨)
- 绘画的基本元素:矩形、路径、文字、和图片
那要如何使用Canvas?
1.1、构造函数
Canvas构造函数有两种:
//空参构造方法
Canvas canvas = new Canvas()
//创建一个装载画布。构造方法中传入的bitmap存储所有绘制在canvas的信息。
Canvas canvas = new Canvas(bitmap)
而在自定义View中获取Canvas对象一般也有两种方法:第一种,我们通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
第二种就是当你想自己创建一个Canvas对象。从上面的基本要素可以明白,一个Canvas对象一定是结合了一个Bitmap对象的。所以一定要为一个Canvas对象设置一个Bitmap对象:
//得到一个Bitmap对象,当然也可以使用别的方式得到。但是要注意,改bitmap一定要是mutable(异变的)
Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
//先new一个Canvas对象,在调用setBitmap方法,一样的效果
//Canvas c = new Canvas();
//c.setBitmap(b);
在android中既然把Canvas当做画布,那么就可以在画布上绘制我们想要的任何东西。除了在画布上绘制之外,还需要设置一些关于画布的属性,比如,画布的颜色、尺寸等。下面列出了一些Canvas的常用方法:
操作类型 | 相关API | 备注 |
---|---|---|
绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 |
绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 |
绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 |
绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 |
绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 |
顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 |
画布剪裁 | clipPath, clipRect | 设置画布的显示区域 |
画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 |
画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、错切 |
Matrix(矩阵) | getMatrix, setMatrix, concat | 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 |
在上面的绘制方法中,我们可以看到经常会引入两个参数:Paint和RectF,那我们下面就介绍一下它们:
2、Paint(画笔)
我们先来看这个类注释:
The Paint class holds the style and color information about how to draw geometries, text and bitmaps.
Paint(画笔)类拥有如何绘制几何图形、文本、位图的颜色和样式等信息。Paint对象有很多设置方法,大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。
2.1、构造函数
//使用默认设置创建画笔
public Paint() {
this(0);
}
/**
* 使用指定的标志创建新的绘画。
* 创建画笔后。使用setFlags()更改设置
*/
public Paint(int flags) {
......
}
/**
* 创建一个新的画笔,
* 使用指定的属性进行初始化画笔参数。
*/
public Paint(Paint paint) {
......
}
我们可以根据需求创建Paint对象。Paint类的native方法和@hide方法比较多,我们就介绍一下它的常用方法:
2.2、图形相关
//设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
setARGB(int a,int r,int g,int b);
//设置绘制图形的透明度。
setAlpha(int a);
//设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。
setColor(int color);
//设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
setAntiAlias(boolean aa);
//设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
setDither(boolean dither);
//如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度,本设置项依赖于dither和xfermode的设置
setFilterBitmap(boolean filter);
//设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
setMaskFilter(MaskFilter maskfilter);
//设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
setColorFilter(ColorFilter colorfilter);
//设置绘制路径的效果,如点画线等
setPathEffect(PathEffect effect);
//设置图像效果,使用Shader可以绘制出各种渐变效果
setShader(Shader shader);
//在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setShadowLayer(float radius ,float dx,float dy,int color);
//设置画笔的样式,
setStyle(Paint.Style style);
//FILL:填充内容
//FILL_AND_STROKE:填充内容+描边
//STROKE:描边
//当画笔样式为STROKE或FILL_AND_STROKE时,设置线帽的图形样式,
setStrokeCap(Paint.Cap cap);
//Cap.BUTT):没有
//Cap.SQUARE:圆的
//Cap.ROUND:方形
//设置绘制时各图形的结合方式,如平滑效果等
setSrokeJoin(Paint.Join join);
//Join.MITER:锐角
//Join.ROUND:圆弧
//Join.BEVEL:直线
//当画笔样式为STROKE或FILL_AND_STROKE时,设置笔刷的粗细度
setStrokeWidth(float width);
//设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
setXfermode(Xfermode xfermode);
2.3、文本相关
// 模拟实现粗体文字,设置在小字体上效果会非常差
setFakeBoldText(boolean fakeBoldText);
// 设置该项为true,将有助于文本在LCD屏幕上的显示效果
setSubpixelText(boolean subpixelText);
// 设置绘制文字的对齐方向
setTextAlign(Paint.Align align);
// 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
setTextScaleX(float scaleX);
// 设置绘制文字的字号大小
setTextSize(float textSize);
// 设置斜体文字,skewX为倾斜弧度
setTextSkewX(float skewX);
// 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
setTypeface(Typeface typeface);
// 设置带有下划线的文字效果
setUnderlineText(boolean underlineText);
//设置带有删除线的效果
setStrikeThruText(boolean strikeThruText);
Paint经常作为参数传入Canvas对象的方法中,两者结合才能看出效果。下面我们看一下Rect类。
3、RectF
先看官方文档注释:
RectF holds four float coordinates for a rectangle. The rectangle is represented by the coordinates of its 4 edges (left, top, right bottom). These fields can be accessed directly. Use width() and height() to retrieve the rectangle's width and height. Note: most methods do not check to see that the coordinates are sorted correctly (i.e. left <= right and top <= bottom)。
RectF 这个类包含一个矩形的四个单精度浮点坐标。矩形通过上下左右4个边的坐标来表示一个矩形。这些坐标值属性可以被直接访问,用width()和 height()方法可以获取矩形的宽和高。注意:大多数方法不会检查这些坐标分类是否错误(也就是left<=right和top<=bottom)。
RectF一共有四个构造方法:
//构造一个无参的矩形
RectF()
//构造一个指定了4个参数的矩形
RectF(float left,float top,float right,float bottom)
//根据指定的RectF对象来构造一个RectF对象(对象的左边坐标不变)
RectF(RectF r)
//根据给定的Rect对象来构造一个RectF对象
RectF(Rect r)
另外还有一个Rect类,两者很相似,不同的地方是Rect类的坐标是用整形表示的,而RectF类的坐标是用单精度浮点型表示的。
三、总结
上面介绍自定义view常用到的几个类Canvas、Paint、RectF。本来准备详细研究下是怎么使用的,发现实在太多了,就放在后面慢慢叙述。
祝:工作愉快!