Android群英传——第六章Canvas的Layer图层

本文介绍了Android Canvas中如何利用save()和restore()进行图层的管理和状态保存。通过save()和saveLayerAlpha()创建图层,然后在栈顶图层进行绘制。restore()用于移除栈顶图层,而restoreToCount()则可以恢复到特定图层数量。测试代码验证了图层出栈后,图像不会消失,而是转移到新的栈顶图层。save()方法还可以接受Flag参数,用于控制图层状态的保存和恢复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 类似于PS的图层,几个图层叠在一起形成一个图片
  • 有了图层后,canvas可以在不同的图层中进行绘画
  • 图层采用栈的方式进行管理:如下所示
    这里写图片描述
  • 使用save() 与 saveLayerAlpha()建立一个图层,入栈
  • 使用restore()[移出栈顶图层]和restoreToCount()[移出图层,让栈中的图层数量为count]
  • 图形的绘制(drawXXX())只会发生在栈顶中
  • 即使用save()创建一个图层后,后续的绘图操作都会在这个图层中进行,知道该图层被从栈中移出
  • 当图层被移出后,他之前所绘制的图像并不会就此消失,而是转移给了新的栈顶的图层,如图:
    这里写图片描述

    测试代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by feathers on 16-11-17.
 */

public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Log.i("logi", "canvas count 1:" + canvas.getSaveCount());

        Paint paint = new Paint();
        canvas.drawColor(Color.WHITE);
        paint.setColor(Color.BLUE);
        canvas.drawCircle(150, 150, 100, paint);

        // 建立了一个图层(指定了透明度变化的区域和透明度的值,可以控制透明度来控制下面图层的显示和隐藏)
            canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), 127, 0);
        Log.i("logi", "canvas count 2:" + canvas.getSaveCount());
        paint.setColor(Color.RED);
        canvas.drawCircle(500, 100, 100, paint);
        canvas.drawCircle(200, 200, 100, paint);

        // 再建立一个图层
        canvas.save();
        Log.i("logi", "canvas count 3:" + canvas.getSaveCount());
        paint.setColor(Color.GREEN);
        canvas.drawRect(10, 10, 25, 25, paint);

        // 再建立一个图层
        canvas.save();
        Log.i("logi", "canvas count 4:" + canvas.getSaveCount());
        paint.setColor(Color.BLACK);
        canvas.drawRect(0, 0, 10, 10, paint);

        // 移出图层,让图层的数量变为2个
        canvas.restoreToCount(2);
        Log.i("logi", "canvas count 5:" + canvas.getSaveCount());
        // 移出栈顶的图层
        canvas.restore();
        Log.i("logi", "canvas count 6:" + canvas.getSaveCount());

    }
}

输出的Log:

I/logi: canvas count 1:1 // 默认拥有一个图层
I/logi: canvas count 2:2 // 图层入栈
I/logi: canvas count 3:3 
I/logi: canvas count 4:4 
I/logi: canvas count 5:2 // 图层出栈,剩余2个图层
I/logi: canvas count 6:1 // 顶部图层出栈

效果图:
这里写图片描述

各个图层绘制的图像仍然存在,并没有随着图层的出栈而消失,说明他们的图像都给了顶栈,最后的顶栈就是默认栈

save()保存状态与restore()恢复状态

save()可以指定一个Flag参数:

int ALL_SAVE_FLAG:调用restore()恢复一切状态
int CLIP_SAVE_FLAG:还原clip
int FULL_COLOR_LAYER_SAVE_FLAG
int HAS_ALPHA_LAYER_SAVE_FLAG
int MATRIX_SAVE_FLAG:还原Matrix

当我们调用save()保存状态时,实际上创建了一个新的图层
这个图层被旋转,移动…. 从而进行方便的绘制,绘制结束时,他也完成了他的任务
此时,这个图层没有任何用处了,有用处的只是他刚刚绘制的图像
所以,我们调用restore()将它移出栈,这样新的栈顶就获得了这个图像
save()有个返回值,查看源码发现:

public int save() {
        return native_save(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
    }

其实save() == save(MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG),所以当我们调用restore时,会把matrix 和 clip 状态还原为入栈时的状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值