自定义控件---图层,画布和canvas

本文详细介绍了Android中图层、画布和canvas的概念,特别是saveLayer的使用,包括saveLayer的绘图流程及其在有无saveLayer情况下的区别。saveLayer创建了一个新的透明图层,后续绘制都在此图层上进行,最后覆盖到原始画布,影响xfermode的合成效果。
摘要由CSDN通过智能技术生成

一: 概念

图层(Layer):

        每一次调用canvas.drawXXX系列函数时,都会生成一个新的透明图层来专门来画这个图形,然后按照绘制的顺序覆盖到画布上。调用完方法就覆盖到画布上了。如果我们连续调用五个draw函数,那么就会生成五个透明图层,画完之后依次盖在画布上显示。 

画布(bitmap):

        每一个画布都是一个bitmap,所有的图像都是画在bitmap上的!

        画布有两种,第一种是view的原始画布,是通过onDraw(Canvas canvas)函数传进来的,其中参数中的canvas就对应的是view的原始画布。 默认只有一个画布。

       另一种是人造画布,通过saveLayer()、new Canvas(bitmap)这些方法来人为新建一个画布。

       一旦调用saveLayer()新建一个画布以后,以后的所有draw函数所画的图像都是画在这个画布上的,只有当调用restore()、resoreToCount()函数以后,才会返回到原始画布上绘制。 

      双缓冲就是创建了新的画布。

Canvas:

      我们可以把Canvas理解成画板,Bitmap理解成透明画纸,而Layer则理解成图层

     每一个draw函数都对应一个图层,在一个图形画完以后,就放在画纸上显示。而一张张透明的画纸则一层层地叠加在画板上显示出来。我们知道画板和画纸都是用夹子夹在一起的,所以当我们旋转画板时,所有画纸都会跟着旋转!当我们把整个画板裁小时,所以的画纸也都会变小了! 这一点非常重要,当我们利用saveLayer来生成多个画纸时,然后最上层的画纸调用canvas.rotate(30)是把画板给旋转了,所有的画纸也都被旋转30度!这一点非常注意 另外,如果最上层的画纸调用canvas.clipRect()将画板裁剪了,那么所有的画纸也都会被裁剪。唯一能够恢复的操作是调用canvas.revert()把上一次的动作给取消掉! 但在利用canvas绘图与画板不一样的是,画布的影响只体现在以后的操作上,以前画上去的图像已经显示在屏幕上是不会受到影响的。 

 关系:

一个canvas可以创建多个画布。一个画布又对应多个图层。图层的内容都是绘制到画布上的。

二:saveLayer()
saveLayer()有两个函数:

[java]  view plain  copy
  1. /** 
  2.  * 保存指定矩形区域的canvas内容 
  3.  */  
  4. public int saveLayer(RectF bounds, Paint paint, int saveFlags)  
  5. public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags)  
  • RectF bounds:要保存的区域的矩形。
  • int saveFlags:取值有:ALL_SAVE_FLAG、MATRIX_SAVE_FLAG、CLIP_SAVE_FLAG、HAS_ALPHA_LAYER_SAVE_FLAG、FULL_COLOR_LAYER_SAVE_FLAG、CLIP_TO_LAYER_SAVE_FLAG总共有这六个,其中ALL_SAVE_FLAG表示保存全部内容,这些标识的具体意义在其他章节介绍;
第二个构造函数实际与第一个是一样的,只不过是根据四个点来构造一个矩形。 
下面我们来看一下例子,拿xfermode来做下试验,来看看saveLayer都干了什么:

[java]  view plain  copy
  1. public class XfermodeView extends View {  
  2.     private int width = 400;  
  3.     private int height = 400;  
  4.     private Bitmap dstBmp;  
  5.     private Bitmap srcBmp;  
  6.     private Paint mPaint;  
  7.   
  8.     public XfermodeView(Context context, AttributeSet attrs) {  
  9.         super(context, attrs);  
  10.   
  11.         setLayerType(View.LAYER_TYPE_SOFTWARE, null);  
  12.         srcBmp = makeSrc(width, height);  
  13.         dstBmp = makeDst(width, height);  
  14.         mPaint = new Paint();  
  15.     }  
  16.   
  17.     @Override  
  18.     protected void onDraw(Canvas canvas) {  
  19.         super.onDraw(canvas);  
  20.         canvas.drawColor(Color.GREEN);  
  21.         //创建了一个新的画布,大小就是矩形大小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值