Android关于Canvas你所知道的和不知道的一切,高级Android开发技术

private void drawColor(Canvas canvas) {
// canvas.drawColor(Color.parseColor(“#E0F7F5”));
// canvas.drawARGB(255, 224, 247, 245);
// 三者等价
canvas.drawRGB(224, 247, 245);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


2.绘制点

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制点
  • @param canvas
    */
    private void drawPoint(Canvas canvas) {
    //绘制点
    canvas.drawPoint(100, 100, mRedPaint);
    绘制一组点,坐标位置由float数组指定(必须是2的倍数个)
    canvas.drawPoints(new float[]{
    400, 400, 500, 500,
    600, 400, 700, 350,
    800, 300, 900, 300
    }, mRedPaint);
    }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


3.绘制直线

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制线
  • @param canvas
    */
    private void drawLine(Canvas canvas) {
    canvas.drawLine(500, 200, 900, 400, mRedPaint);
    //绘制一组点,坐标位置由float数组指定(必须是4的倍数个)
    canvas.drawLines(new float[]{
    200, 200, 400, 200,
    400, 200, 200, 400,
    200, 400, 400, 400
    }, mRedPaint);
    }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


4.绘制矩形

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制矩形
  • @param canvas
    */
    private void drawRect(Canvas canvas) {
    canvas.drawRect(100, 100, 500, 300, mRedPaint);
    //等价上行
    // Rect rect = new Rect(100, 100, 500, 300);
    // canvas.drawRect(rect,mRedPaint);
    //(左上右下X圆角,Y圆角)
    canvas.drawRoundRect(100 + 500, 100, 500 + 500, 300, 50, 50, mRedPaint);
    }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


5.绘制类圆

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制类圆
  • @param canvas
    */
    private void drawLikeCircle(Canvas canvas) {
    //绘制圆(矩形边界,画笔)
    canvas.drawCircle(650, 200, 100, mRedPaint);
    // canvas.drawOval(100, 100, 500, 300, mRedPaint);
    //等价上行
    //绘制椭圆(矩形边界,画笔)
    RectF rect = new RectF(100, 100, 500, 300);
    canvas.drawOval(rect, mRedPaint);

RectF rectArc = new RectF(100 + 500, 100, 500 + 500, 300);
//绘制圆弧(矩形边界,开始角度,扫过角度,使用中心?边缘两点与中心连线区域:边缘两点连线区域)
canvas.drawArc(rectArc, 0, 90, true, mRedPaint);

RectF rectArc2 = new RectF(100 + 500 + 300, 100, 500 + 500 + 300, 300);
//绘制圆弧(矩形边界,开始角度,扫过角度,使用中心?边缘两点与中心连线区域:边缘两点连线区域)
canvas.drawArc(rectArc2, 0, 90, false, mRedPaint);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


6.绘制图片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制图片
  • @param canvas
    */
    private void drawBitmap(Canvas canvas) {
    //1.定点绘制图片
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.menu_bg);
    canvas.drawBitmap(bitmap, 100, 100, mRedPaint);
    //2.适用变换矩阵绘制图片
    Matrix matrix = new Matrix();
    //设置变换矩阵:缩小3倍,斜切0.5,右移150,下移100
    matrix.setValues(new float[]{
    1, 0.5f, 1500 * 3,
    0, 1, 100 * 3,
    0, 0, 3
    });
    canvas.drawBitmap(bitmap, matrix, mRedPaint);

//3.图片适用矩形区域不剪裁
RectF rectf1 = new RectF(100 + 900, 100, 600 + 900, 400);
canvas.drawBitmap(bitmap, null, rectf1, mRedPaint);

//4.图片裁剪出的矩形区域
Rect rect = new Rect(300, 300, 400, 400);
//图片适用矩形区域
RectF rectf2 = new RectF(100 + 900, 100 + 400, 600 + 900, 400 + 400);
canvas.drawBitmap(bitmap, rect, rectf2, mRedPaint);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


7.绘制Picture

1).一开始挺纳闷Picture不就是图片吗?然后翻了一下API:

/**

  • A Picture records drawing calls (via the canvas returned by beginRecording)
  • and can then play them back into Canvas (via {@link Picture#draw(Canvas)} or
  • {@link Canvas#drawPicture(Picture)}).For most content (e.g. text, lines, rectangles),
  • drawing a sequence from a picture can be faster than the equivalent API
  • calls, since the picture performs its playback without incurring any
  • method-call overhead.
  • Note: Prior to API level 23 a picture cannot

  • be replayed on a hardware accelerated canvas.

一个Picture类记录绘制(通过beginRecording方法返回的Canvas),可以展示这个Canvas
到其他Canvas上(通过Picture#draw(Canvas)或者Canvas#drawPicture(Picture)),
对于大多数的内容,从picture绘制都要比相应的API要快速,因为picture的展现不会招致方法调用开销
在API级别23之前,无法在硬件加速画布上展示Picture(自译,仅供参考)

2).通过一段代码你就能很清楚它是干嘛用的

如果绘制一个品字,需要这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

private void drawPicture(Canvas canvas) {
canvas.drawRect(100, 0, 200, 100, mRedPaint);
canvas.drawRect(0, 100, 100, 200, mRedPaint);
canvas.drawRect(200, 100, 300, 200, mRedPaint);
}

如果想要复用这个品字形,大多数人知道,平移画布,复制粘贴,

对于少量的代码,这还可以接收,如果是非常复杂的图形,每次绘制重复的内容,会浪费性能

private void drawPicture(Canvas canvas) {
//创建Picture对象
Picture picture = new Picture();
//确定picture产生的Canvas元件的大小,并生成Canvas元件
Canvas recodingCanvas = picture.beginRecording(canvas.getWidth(), canvas.getHeight());
//Canvas元件的操作
recodingCanvas.drawRect(100, 0, 200, 100, mRedPaint);
recodingCanvas.drawRect(0, 100, 100, 200, mRedPaint);
recodingCanvas.drawRect(200, 100, 300, 200, mRedPaint);
//Canvas元件绘制结束
picture.endRecording();

canvas.save();
canvas.drawPicture(picture);//使用picture的Canvas元件
canvas.translate(0, 300);
picture.draw(canvas);//同上:使用picture的Canvas元件
canvas.drawPicture(picture);
canvas.translate(350, 0);
canvas.drawPicture(picture);
canvas.restore();

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture相当于先拍一张照片,并且是在别的Canvas上,在别的Canvas上,在别的Canvas上!
重要的话说三遍:当需要的时候在贴在当前的canvas上,picture绘制的优势就是节能减排
当有大量复杂内容需要复用,Picture这个的canvas元件是不二的选择:


8.绘制文字(文字的效果有Paint决定,细节将在Paint篇介绍)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 绘制文字
  • @param canvas
    */
    private void drawText(Canvas canvas) {
    mRedPaint.setTextSize(100);
    canvas.drawText(“张风捷特烈–Toly”, 200, 300, mRedPaint);
    }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无聊的代码终于敲完了,进入正题。


三、Canvas的画布变换

以前对Canvas的变换很厌倦,现在看了键值是神技

作为一代PS大神的我,理解Canvas状态保存与恢复本应易如反掌,为何最近才豁然开朗

1.先看下面的图形:将坐标系原点设为(500,500)

private void stateTest(Canvas canvas) {
canvas.drawLine(mCoo.x + 500, mCoo.y + 200, mCoo.x + 900, mCoo.y + 400, mRedPaint);
// canvas.rotate(45);
canvas.drawRect(mCoo.x + 100, mCoo.x + 100, mCoo.y + 300, mCoo.y + 200, mRedPaint);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题来了,想画一个斜45度的矩形怎么办?

貌似没有斜矩形的API,一个一个点找,貌似太麻烦了,我把纸转一下不就行了吗!
纸就是Canvas,看一下API,果然有rotate()方法,怀着忐忑的心情:

private void stateTest(Canvas canvas) {
canvas.drawLine(mCoo.x + 500, mCoo.y + 200, mCoo.x + 900, mCoo.y + 400, mRedPaint);
canvas.rotate(45);
canvas.drawRect(mCoo.x + 100, mCoo.x + 100, mCoo.y + 300, mCoo.y + 200, mRedPaint);
}

果然转得天翻地覆

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


2.图层的概念

PS中的图层可谓PS的精华,它保证了在一个图层中绘制而不会影响到其他的图层

在Canvas中每次的save()都存将先前的状态保存下来,产生一个新的绘图层,
我们可以随心所欲地地画而不会影响其他已画好的图,最后用restore()将这个图层合并到原图层
这像是栈的概念,每次save(),新图层入栈(注意可以save多次),只有栈顶的层可以进行操作,restore()弹栈

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


3.旋转画布:rotate()

private void stateTest(Canvas canvas) {
canvas.drawLine(mCoo.x + 500, mCoo.y + 200, mCoo.x + 900, mCoo.y + 400, mRedPaint);
canvas.drawRect(mCoo.x + 100, mCoo.x + 100, mCoo.y + 300, mCoo.y + 200, mRedPaint);
canvas.save();//保存canvas状态
//(角度,中心点x,中心点y)
canvas.rotate(45, mCoo.x + 100, mCoo.y + 100);
mRedPaint.setColor(Color.parseColor(“#880FB5FD”));
canvas.drawRect(mCoo.x + 100, mCoo.x + 100, mCoo.y + 300, mCoo.y + 200, mRedPaint);
canvas.restore();//图层向下合并
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.平移画布:translate():写一堆mCoo,也就是让画布移动一下而已

效果必变,是不是清爽许多

private void stateTest(Canvas canvas) {
canvas.save();
canvas.translate(mCoo.x, mCoo.y);//将原点平移到坐标系原点
canvas.drawLine(500, 200, 900, 400, mRedPaint);
canvas.drawRect(100, 100, 300, 200, mRedPaint);
canvas.save();//保存canvas状态
//(角度,中心点x,中心点y)
canvas.rotate(45, 100, 100);
mRedPaint.setColor(Color.parseColor(“#880FB5FD”));
canvas.drawRect(100, 100, 300, 200, mRedPaint);
canvas.restore();//图层向下合并
canvas.restore();
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.缩放画布:scale()

private void stateTest(Canvas canvas) {
canvas.save();
canvas.translate(mCoo.x, mCoo.y);//将原点平移到坐标系原点
canvas.drawLine(500, 200, 900, 400, mRedPaint);
canvas.drawRect(100, 100, 300, 200, mRedPaint);
canvas.save();//保存canvas状态
//(角度,中心点x,中心点y)
canvas.scale(2, 2, 100, 100);
mRedPaint.setColor(Color.parseColor(“#880FB5FD”));
canvas.drawRect(100, 100, 300, 200, mRedPaint);
canvas.restore();//图层向下合并
canvas.restore();
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6.斜切画布:scale()

private void stateTest(Canvas canvas) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结:

面试是一个不断学习、不断自我提升的过程,有机会还是出去面面,至少能想到查漏补缺效果,而且有些知识点,可能你自以为知道,但让你说,并不一定能说得很好。

有些东西有压力才有动力,而学到的知识点,都是钱(因为技术人员大部分情况是根据你的能力来定级、来发薪水的),技多不压身。

附上我的面试各大专题整理: 面试指南,满满的都是干货,希望对大家有帮助!

只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-wMbb0Lgy-1711735010015)]

总结:

面试是一个不断学习、不断自我提升的过程,有机会还是出去面面,至少能想到查漏补缺效果,而且有些知识点,可能你自以为知道,但让你说,并不一定能说得很好。

有些东西有压力才有动力,而学到的知识点,都是钱(因为技术人员大部分情况是根据你的能力来定级、来发薪水的),技多不压身。

附上我的面试各大专题整理: 面试指南,满满的都是干货,希望对大家有帮助!
[外链图片转存中…(img-2yZC6N5K-1711735010015)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值