Canvas(画布),制作的载体,能够经过Paint(画笔)在上面制作一切你想制作的图画。
1、Canvas制作API
其包括一系列drawXXX办法: 1、制作色彩
public void drawColor(int color)
public void drawARGB(int a, int r, int g, int b)
public void drawRGB(int r, int g, int b)
2、制作形状
- 制作点
void drawPoint(float x, float y, Paint paint)
void drawPoints(float[] pts, Paint paint)
void drawPoints(float[] pts, int offset, int count, Paint paint)
- 制作线段
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
void drawLines(float[] pts, int offset, int count, Paint paint)
void drawLines(float[] pts, Paint paint)
- 制作矩形
void drawRect(RectF rect, Paint paint)
void drawRect(Rect r, Paint paint)
void drawRect(float left, float top, float right, float bottom, Paint paint)
- 制作圆角矩形,与shape标签不同的是,它不能独自设置4个圆角
void drawRoundRect(RectF rect, float rx, float ry, Paint paint)
void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
- 制作双框圆角矩形
void drawDoubleRoundRect( RectF outer, float outerRx, float outerRy, RectF inner, float innerRx, float innerRy, Paint paint)
/**
* 这个办法经过表里边框来完结制作,且表里边框的四个角的圆角半径都可控
* @param outer 外边框的规模
* @param inner 内边框的规模
* @param innerRadii、outerRadii
* 这两个float数组别离保存了表里边框的四个角的圆角半径
* 每个数组需求传入8个float,每两个为一组 rx,ry即圆角半径在x,y方向的值
* @param paint 这儿我传入的paint里边保存着bitmapShader
* 此外需求留意设置Style:
* FILL将会制作到两个矩形(RectF)中心的内容
* STROKE,便是会把两个边框给制作出来。
*/
void drawDoubleRoundRect(RectF outer, float[] outerRadii, RectF inner, float[] innerRadii, Paint paint)
- 制作圆
void drawCircle(float cx, float cy, float radius, Paint paint)
- 制作椭圆
void drawOval(RectF oval, Paint paint)
void drawOval(float left, float top, float right, float bottom, Paint paint)
- 制作弧
void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
- 制作途径
void drawPath(Path path, Paint paint)
3、制作图画
void drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
void drawPicture(Picture picture)
void drawPicture(Picture picture, RectF dst)
android.graphics.Picture
相对于Drawable和Bitmap来说,更加小巧,它并不存储实践的像素,只是记录了每个制作的进程。运用介绍
4、制作文字
- 制作惯例文字
void drawText(char[] text, int index, int count, float x, float y, Paint paint)
void drawText(String text, float x, float y, Paint paint)
void drawText(String text, int start, int end, float x, float y, Paint paint)
void drawText(CharSequence text, int start, int end, float x, float y, Paint paint)
留意:这儿x和y坐标别离表示文字起始方位和文字基线方位坐标。
- 沿途径制作文字
void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
void drawTextOnPath(String text, @NonNull Path path, float hOffset, float vOffset, Paint paint)
- float hOffset:与途径起始点的水平偏移量
- float vOffset:与途径起始点的垂直偏移量
- drawTextRun 对汉字没用,能够不必了解
void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, boolean isRtl, Paint paint)
void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint paint)
void drawTextRun(MeasuredText text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint paint)
- 其余:
public void drawPaint(Paint paint)
制作3D图形利器
void drawVertices(@NonNull VertexMode mode, int vertexCount, @NonNull float[] verts,
int vertOffset, @Nullable float[] texs, int texOffset, @Nullable int[] colors,
int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount,
@NonNull Paint paint)
2、Canvas改换操作
1、每次调用drawXXX系列函数来绘图时,都会产生一个全新的Canvas通明图层。
2、如果在调用drawXXX系列函数前,调用平移、旋转等函数对Canvas进行了操作,那么这个操作是不可逆的。每次产生的画布的状况都是执行这些操作后的状况。
3、在Canvas图层与屏幕合成时,超出屏幕规模的图画是不会显示出来的。
Canvas改换只会影响后续制作内容。
- 1、平移操作
void translate(float dx, float dy) `
- 2、缩放操作
void sacle(float sx, float sy)`
//相当于先translate(dx, dy),再sacle(sx, sy),再反向translate(-dx, -dy)
void sacle(float sx, float sy, float dx, float dy)
- 3、旋转操作
void rotate(float degress)
void rotate(float degress, float px, float py)
- 4、倾斜操作
void skew(float sx, float sy)
- 5、Matrix,经过矩阵等操作Canvas
void setMatrix(Matrix matrix)
3、Canvas裁剪
切割操作,只能制作图画到指定区域内
void clipXXX(...)
反切割操作,只能制作图画到指定区域外
void clipOutXXX(...)
留意:clip系列函数需求禁用硬件加速功用
setLayerType (LAYER_TYPE_SOFTWARE,null)
4、状况康复与保存
当Canvas经过改换操作或裁剪操作后,后续操作都是基于改换后的Canvas,都将受到影响。所以Canvas提供save
、restore
和restoreToCount
办法来保存和康复状况。
- 1、save
int save()
会保存当时Canvas的Matrix
和Clip
等信息到Canvas的私有栈中。
回来当时栈的方位,可作为Canvas.restoreToCount()
的入参,用于快速康复到当时状况。
- 2、restore
void restore()
Canvas的私有栈中康复Matrix
和Clip
等信息。
- 3、restoreToCount
void restoreToCount(int saveCount)
与restore()
类似,但restore()
只能依次从私有栈中弹出,而restoreToCount()
,能够弹出到私有栈中特定的方位。
示例代码如下:
canvas.drawRect(100, 100, 300, 300, paint);
int count = canvas.save();
canvas.rotate(45, 200, 200);
paint.setColor(Color.GRAY);
canvas.drawRect(100, 100, 300, 300, paint);
canvas.restoreToCount(count);
canvas.drawLine(200, 100, 200, 300, paint);
5、离屏烘托
离屏烘托,意思是把内容制作到独自的缓冲画布中,从而保证制作的内容不受旧画布的影响。一般配合Xfermode
运用,同时需求禁止硬件加速。
Android经过了saveLayer
、saveLayerAlpha
两个办法来完成离屏烘托。它们能够为Canvas创立一个缓冲画布,后续对该Canvas的操作都将基于最新的画布上来完结。
- saveLayer
int saveLayer(RectF bounds, Paint paint)
int saveLayer(float left, float top, float right, float bottom, Paint paint)
创立缓冲画布,并保存画笔目标,并在离屏烘托完毕后,画布restore()时,将缓冲画布用该画笔与旧画布进行混合。
- saveLayerAlpha
int saveLayerAlpha(RectF bounds, int alpha)
int saveLayerAlpha(float left, float top, float right, float bottom, int alpha)
创立缓冲画布,在离屏烘托完毕后,画布restore()时,将缓冲画布用alpha与旧画布进行混合。
一般流程是:先制作目标图
(dst),然后设置Xfermode
,再制作原图
(src),最终铲除Xfermode
。
代码如下:
//禁止运用硬件加速
setLayerType(View.LAYER_TYPE_HARDWARE, null);
//离屏制作
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), paint, Canvas.ALL_SAVE_FLAG);
//制作目标图
canvas.drawBitmap(createDstBitmap(), 0, 0, paint);
//设置混合形式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
//制作原图
canvas.drawBitmap(createSrcBitmap(), 0, 0, paint);
//铲除混合形式
paint.setXfermode(null);
canvas.restoreToCount(layerId);
更多有关Xfermode和硬件加速的常识,请参阅:Android制作常识总结(Xfermode和硬件加速)