Canvas中的Layer图层

前言

一个复杂的图形可能是有几个图层构成的,Canvas中提供了操作图层的相关的方法,缺省情况可以看作是只有一个图层Layer。如果需要按层次来绘图,Android的Canvas可以使用SaveLayerXXX,Restore来创建一些中间层,对于这些Layer是按照“栈结构“来管理的:

此处输入图片的描述

创建一个新的Layer到“栈”中,可以使用saveLayer, savaLayerAlpha, 从“栈”中推出一个Layer,可以使用restore,restoreToCount。但Layer入栈时,后续的DrawXXX操作都发生在这个Layer上,而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上。

此处输入图片的描述

saveLayer

saveLayer会创建一个新的图层,解下来的绘制操作都是在这个新的图层上面进行的,调用restore方法之后,新图层上绘制的内容会合并到canvas或者上一个图层上面。

  • public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint)

  • public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint)

两个方法是一样的,只不过是第一个方法接收的是RectF,第二个是坐标。都是指定Layer的大小和范围的。

1
2
3
4
5
6
7
8
paint.setColor(Color.BLUE);
int count=canvas.saveLayer(0,0,1000,1000,paint);
canvas.translate(200, 200);
canvas.drawRect(100, 100, 300, 300, paint);
canvas.restoreToCount(count);

paint.setColor(Color.RED);
canvas.drawRect(100, 100, 300, 300, paint);

效果图:
此处输入图片的描述

canvas.restoreToCount(count)方法会将图层恢复到count图层之前的状态,并将这个图层之上的图层上绘制的内容,都合并到图层或者canvas上。

示例代码:

1
2
3
4
5
6
mPaint.setColor(Color.BLUE);
int count1=canvas.saveLayer(0,0,1000,1000,mPaint);
canvas.drawRect(100, 100, 300, 300, mPaint);
int count2=canvas.saveLayer(0,0,1000,1000,mPaint);
canvas.drawRect(300, 300, 500, 500, mPaint);
canvas.restoreToCount(count1);

效果图:
此处输入图片的描述

可以看到count2图层上的内容也被合并到了canvas上面了。

saveLayerAlpha

这个方法会创建一个带有透明度的图层,在这个图层上面绘制的图层都带有透明度,当需要绘制具有透明度效果的图形的时候,这个方法是比较有用的。

  • public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha)

  • public int saveLayerAlpha(@Nullable RectF bounds, int alpha)

alpha的取值的范围是0-255,0代表完全透明,255代表完全不透明。
示例代码:

1
2
3
4
5
6
7
paint.setColor(Color.BLUE);
canvas.drawCircle(100, 100, 100, paint);

paint.setColor(Color.RED);
canvas.saveLayerAlpha(100, 100, 300, 300, 120, Canvas.ALL_SAVE_FLAG);
canvas.drawCircle(200, 200, 100, paint);
canvas.restore();

效果图:
此处输入图片的描述

saveFlags

关于saveLayer方法和saveLayerAlpha方法,都存在有saveFlags值的方法:

saveLayer

  • public int saveLayer(RectF bounds, Paint paint, int saveFlags)
  • public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags)

saveLayerAlpha

  • public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
  • public int saveLayerAlpha(float left, float top, float right, float bottom,int alpha, int saveFlags)

在高版本的Android SDK中,带saveFlags的方法已经被标注为过时了,不推荐使用,如果想了解这些参数的作用话,可以阅读:android canvas layer (图层)详解与进阶。这篇文章中,关于介绍saveFlags的值的几个例子,最好自己运行一下,我运行的几个例子是有问题的。

示例代码:CanvasLayer.java

参考链接:

Android Canvas 方法总结

android canvas layer (图层)详解与进阶

Canvas的saveLayer理解

canvas变换

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器