Android Canvas

一、简介

Canvas即画布,在自定义View中常用到,它可以通过直接new Canvas()或者new Canvas(Bitmap bitmap)初始化,但我们在使用过程中更多的是通过onDraw(Canvas canvas)得到Canvas对象。

我这里大概将Canvas的功能分为三类

1、绘制各种形状或线条,有如下方法:

drawARGB、drawARC、drawBitmap、drawCircle、drawColor、drawLine、drawOval和drawPath等方法。

2、各种变换操作,如平移、缩放、旋转、倾斜和切割等。

3、状态的保存和恢复。

绘制各种形状和线条相关的方法不在这里讲述,我们主要讲第二三类,在里面也会涉及到绘制相关的内容。

 

二、变换操作

1、平移

    private Paint mPaint;

    public TransformView(Context context) {
        this(context, null);
    }

    public TransformView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TransformView(Context context, @Nullable AttributeSet attrs, int     defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(4);
        mPaint.setStyle(Paint.Style.STROKE);
    }

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

        //平移
        //先画一个矩形
        Rect rect = new Rect(0, 0, 400, 400);
        canvas.drawRect(rect, mPaint);
        //将画布平移到位置(100, 100)
        canvas.translate(100, 100);
        //更换颜色后再画一个矩形
        mPaint.setColor(Color.BLUE);
        canvas.drawRect(rect, mPaint);
        //从平移后的位置划线
        mPaint.setColor(Color.GREEN);
        canvas.drawLine(0, 0, 400, 400, mPaint);

    }

首先在构造方法中初始化了一个画笔,颜色设置成红色,然后在onDraw方法中先画了一个矩形,注意原点(0, 0)的位置在右上角,往右是X轴的正方向,往下是Y轴的正方向。然后将画布移到(100, 100)的位置,此时画布的原点就在(100, 100)位置了,移动后右画了一个矩形,最后画了一根直线,效果如下:

 

2、缩放

        //缩放
        Rect rect = new Rect(200, 200, 400, 400);
        canvas.drawRect(rect, mPaint);
        //整个画布及尺寸都缩小0.5倍
        //canvas.scale(0.5f, 0.5f);
        //整个画布及尺寸都缩小0.5倍,再从坐标(200, 200)处重新绘制
        canvas.scale(0.5f, 0.5f, 200, 200);
        mPaint.setColor(Color.GRAY);
        canvas.drawRect(rect, mPaint);

缩放操作有两个方法scale(sx, sy)和scale(sx, sy, px, py),第一个方法的参数只有xy方向的缩放尺寸,第二个除了xy方向的缩放尺寸外px和py表示缩放后以该点为原点重新绘制。效果如下:

 

3、旋转

        //旋转
        Rect rect = new Rect(400, 400, 900, 900);
        canvas.drawRect(rect, mPaint);
        //以px、py为原点旋转
        canvas.rotate(45, 400, 400);
        mPaint.setColor(Color.BLUE);
        canvas.drawRect(400, 400, 900, 900, mPaint);

首先绘制一个红色的矩形,然后以px、py(400, 400)为原点旋转45度,再绘制一个蓝色的矩形,效果如下:

 

4、倾斜

        //倾斜
        Rect rect = new Rect(0, 0, 400, 400);
        canvas.drawRect(rect, mPaint);
        //x方向上倾斜45度
        canvas.skew(1.0f, 0);
        mPaint.setColor(Color.BLUE);
        canvas.drawRect(rect, mPaint);

skew(sx, sy),sx表示在X轴方向倾斜,sy表示在Y轴方向倾斜,1.0f是由正切函数tan A = 对边 / 邻边得到,如下图:

效果如下:

 

5、切割

        //切割
        Rect rect = new Rect(0, 0, 400, 400);
        canvas.drawRect(rect, mPaint);
        canvas.clipRect(100, 100, 300, 300);
        mPaint.setColor(Color.GREEN);
        //只在切割后的区域内绘制有效
        canvas.drawLine(100, 100, 300, 300, mPaint);

首先绘制一个矩形,然后在矩形里面将一部分区域切割出来,最后在切割的区别画一条直线,如果划线的地方不在切割区域内,则无法正常显示,效果如下:

 

6、矩阵

        //矩阵
        Rect rect = new Rect(0, 0, 400, 400);
        canvas.drawRect(rect, mPaint);
        Matrix matrix = new Matrix();
        //平移
        matrix.setTranslate(50, 50);
        //旋转
        //matrix.setRotate(45);
        canvas.setMatrix(matrix);
        mPaint.setColor(Color.GREEN);
        canvas.drawRect(rect, mPaint);

通过Matrix可以实现以上5种操作,如平移、旋转等,效果如下:

 

三、状态的保存和恢复

        Rect rect = new Rect(100, 100, 400, 400);
        canvas.drawRect(rect, mPaint);
        canvas.save();
        //在平移前保存状态
        canvas.translate(100, 100);
        mPaint.setColor(Color.BLACK);
        canvas.drawRect(rect, mPaint);
        //恢复到平移前的状态
        canvas.restore();
        //在最初的状态画线
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 0, 600, 600, mPaint);

效果如下:

首先绘制了一个红色的矩形,此时保存了一个状态,然后将画布移动到(100, 100)位置,再绘制一个黑色的矩形,注意绘制两个矩形的参数都相同,最后恢复画布到初始状态,绘制一条蓝色的直线。

为什么需要状态的保存和恢复,比如我们做了一些上面讲的平移、缩放、旋转等操作后,如果想绘制下一个图形时是在以上操作之前的状态绘制,那么我们需要执行一个反向的操作,比如:刚开始执行了setTranslate(100, 100),使画布移动了以(100,100)为原点的位置,这时我又想在最初的原点(0, 0)绘制一条直线,那么我们需要反向执行setTranslate(0, 0)才行,如果是一次这种操作还好,但是多次执行移动、缩放、旋转等操作,再回到某个初始状态就比较麻烦了。

canvas.save()一般在执行变换前调用,保存好状态,canvas.restore()是在我们想回到某一状态时调用,restore与save是成对使用的,还有一个方法是canvas.restoreToCount(int savaCount),savaCount这个值是我们调用save方法时会返回的,restoreToCount表示我想恢复到哪次保存的状态,只需要传入其保存时对应的savaCount即可。

关于Canvas大概就讲到这里,希望能帮助到大家,谢谢!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值