美文网首页
Android Canvas总结

Android Canvas总结

作者: 刘小厨 | 来源:发表于2020-04-01 18:40 被阅读0次

    前言

    Android 中的Canvas相当于是画布,通过画笔绘制几何图形,文本,路径和位图等;
    常用Api分类:

    1. 绘制
    2. 变换
    3. 状态保存/恢复

    简单看下第一种分类,不做重点介绍

    绘制相关

    void drawText(String text,int start, int end,Paint paint) //指定坐标 绘制文字
    void drawPoint(float x, float y,Paint paint) //指定坐标 绘制点
    void drawLine(float startX, float startY,float endX, float endY,Paint paint) //指定起始点,结束点 绘制连线
    void drawPath(Path path,Paint paint) //指定path 绘制连线
    void drawBitmap(Bitmap bitmap,float left,float top,Paint paint) //指定坐标,绘制位图
    void drawCircle(float cx, float cy, float radius,  Paint paint) //绘制圆形
    void drawRect(RectF rect,Paint paint) //绘制矩形
    等等等...
    

    位置/形状 变换相关

    void translate(float dx, float dy) //平移操作
    void scale(float sx, float sy) //缩放操作
    void rotate(float degrees) //旋转操作
    void skew(float sx, float sy) //倾斜操作
    void clipXxx(...) //切割操作,参数指定区域内可以正常(继续)绘制
    void clipOutXxx(...) //反向切割操作,参数指定区域内不可以正常(继续)绘制
    void setMatrix(Matrix matrix) :可通过matrix实现平移,缩放,旋转等操作
    
    • translate(float dx, float dy)平移操作,操作画布平移,相当于绘制的参考点坐标平移,从坐标系的角度来说比较简单,直接看图:
      translate(float dx, float dy)
    • scale(float sx, float sy) 缩放操作,传入x,y方向的缩放比例,我们看下缩放前后对比(红色矩形为缩放前绘制,灰色矩形为缩放后绘制):
    canvas.drawRect(200,200, 700,700, mPaint);
    canvas.scale(0.5f, 0.5f);
    mPaint.setColor(Color.GRAY);
    canvas.drawRect(200,200, 700,700, mPaint);
    
    scale(float sx, float sy)

    scale(float sx, float sy) 操作对整个画布缩放操作,所以缩放后的绘制的矩形对比之前的,位置和大小都发生了变化,缩放操作还有个重载方法,需要四个参数void scale(float sx, float sy, float px, float py),我们看下前后对比

    canvas.drawRect(200,200, 700,700, mPaint);
    //先translate(px, py),再scale(sx, sy),再反向translate(px, py)
    canvas.scale(0.5f, 0.5f,200,200);
    mPaint.setColor(Color.GRAY);
    canvas.drawRect(200,200, 700,700, mPaint);
    
    void scale(float sx, float sy, float px, float py)

    上述canvas.scale(0.5f, 0.5f,200,200)操作相当于一下三行代码:

    //先translate(px, py)
    canvas.translate(200, 200);
    //再scale(sx, sy)
    canvas.scale(0.5f, 0.5f);
    //再反向translate(px, py)
    canvas.translate(-200, -200);
    
    • rotate(float degrees) 旋转操作
      还有一个重载方法:
      void rotate(float degrees, float px, float py) //px, py表示旋转中心的坐标
      默认顺时针旋转,直接看图:
    canvas.drawRect(400, 400, 900, 900, mPaint);
    canvas.rotate(45, 650, 650); //px, py表示旋转中心的坐标
    mPaint.setColor(Color.GRAY);
    canvas.drawRect(400, 400, 900, 900, mPaint);
    
    rotate(float degrees, float px, float py)
    • void skew(float sx, float sy) 倾斜操作参数分别表示x,y方向倾斜的角度的tan值
    canvas.drawRect(0,0, 400, 400, mPaint);
    canvas.skew(1, 0); //在X方向倾斜45度,相当于Y轴逆时针旋转45
    mPaint.setColor(Color.GRAY);
    canvas.drawRect(0, 0, 400, 400, mPaint);
    
    canvas.skew(1, 0)

    如果在y方向倾斜45度的话

    canvas.skew(0, 1); //在y方向倾斜45度, 相当于X轴顺时针旋转45
    
    canvas.skew(0, 1)
    • void clipXxx(...) //切割操作,参数指定区域内可以正常(继续)绘制,不在赘述

    • void clipOutXxx(...) //反向切割操作,参数指定区域内不可以正常(继续)绘制,不在赘述

    • void setMatrix(Matrix matrix) 矩阵
      Matrix类里面封装了一系列的api,比如:

    Matrix matrix = new Matrix();
    matrix.setTranslate(50,50);//平移
    matrix.setRotate(45);//旋转
    matrix.setScale(0.5f, 0.5f);//酸防
    canvas.setMatrix(matrix);
    canvas.drawRect(0,0,700,700, mPaint);
    

    状态保存和恢复

    调用了translate,scale,rotate,skew,clipRect等变换后,后续的操作都是基于
    变换后的Canvas,都会受到影响,对于后续的操作很不方便。Canvas提供 了save, saveLayer, saveLayerAlpha, restore,restore ToCount来保存和恢复状态。

    Canvas 的save()和restore()可以多次调用,Canvas内部维护了一个状态栈,每次save()操作会将当前状态压栈,每次restore()操作会将最上面的状态出栈,恢复到上次保存的状态

    状态栈

    我们也可以调用canvas.getSaveCount()获取当前保存的状态数,不进行任何的save()操作,getSaveCount()默认为1,调用canvas.getSaveCount()恢复到指定状态,参数为save()操作返回的int

    int state = canvas.save(); //保存状态1
    Log.e("TAG", "onDraw: " + canvas.getSaveCount());
    canvas.translate(70, 50);
    canvas.drawRect(0, 0, 400, 400, mPaint);
    canvas.save(); //保存状态2
    canvas.restore(); //返回最新状态(状态2)
    Log.e("TAG", "onDraw: " + canvas.getSaveCount());
    mPaint.setColor(Color.BLUE);
    canvas.drawRect(0, 0, 400, 400, mPaint);
    canvas.restoreToCount(state);//手动指定的返回到状态1
    
    

    Canvas的总结就到这里,使用Canvas实现小案例见:

    相关文章

      网友评论

          本文标题:Android Canvas总结

          本文链接:https://www.haomeiwen.com/subject/gyjauhtx.html