在前面我们说了Android的基本绘图技巧,下面我们聊聊Android中常用的一些绘图技巧。通过这些技巧学习来简化、优化Android的绘图操作。

一、Canvas

Canvas作为绘制图形的直接对象,提供了以下几个非常有用的方法。

●  Canvas.save()

●  Canvas.restore()

●  Canvas.translate()

●  Canvas.rotate()

首先,来看Canvas.save()和Canvas.restore()这两个方法。

在讲解这两个方法之前,首先来了解一下Android的绘图坐标体系,在Android中,默认的坐标零点位于屏幕左上角,向下为Y轴正方形,向右为X轴的正方向。Android中的绘图,一般情况下困难在于坐标的计算上。因此绘图者不应该把自己看作是一个完成任务的人,而是应该把自己当成一个设计者,你是在设计这些图形而不是在机械地绘制。

Canvas.save()这个方法,从字面上可以理解为保存画布。它的作用就是将之前的所有已绘制图像保存起来,让后续的操作就好像在一个新的图层上操作一样,这一点与Photoshop中的图层理解基本一致。

而Canvas.restore()这个方法,则可以理解为Photoshop中的合并图层操作。它的作用是将我们在save()之后绘制的所有图像与save()之前的图像进行合并。

那么translate()方法与rotate()方法呢?虽热从字面上看,可以将它们理解为画布平移、画布翻转,但是把它理解为坐标系的平移和翻则会更加形象。前面说了,默认绘图坐标零点位于屏幕左上角,那么在调用translate(x,y)方法之后,则将原点(0,0)移动到了(x,y)。之后所有的绘图操作都将以(x,y)为原点执行。同理,rotate()方法也是一样,它将坐标系旋转一定的角度。大家也想会想,这样的操作有什么用呢?的确,没有这两个方法,同样可以绘图,只要计算好坐标,没有什么画画不出来的。所以说,这些方法是Android用来帮助我们简化绘图而创建的。这么说可能比较抽象,来看一个具体的实例,大家就能明白其中的奥妙了。例如,需要创建一和如图(1)所示的仪表盘。

(1)仪表盘

先来分析一下要画的这个图形。要完成这样一个图形,可以将它分解成以下几个元素。

1、仪表盘——外面的大圆盘

2、刻度线——包含四个长的刻度线和其他短的刻度线

3、刻度值——包含长刻度线对应的大的刻度值和其他小的刻度值

4、指针——中间的指针,一粗一细两根指针

相信如果在现实中叫你去画这样一个仪表盘,你应该也会这样去画。实际上,Android中的绘图与实现中的绘图十分相似,与Photoshop中的绘图则更是相似。所以,当你要绘制一个复杂的图形的时候,不妨想想自己在显示中该如何去做,顺着这个思路也许就能找到解决问题的方法了。

在这个实例中,第一步画圆盘,已经可以轻松的实现了,也就是调用xanvas.drawCircle(方法绘制一个圆就可以了。关键在于确定圆心和半径。这里为了简单演示,我们把圆心定在屏幕中心而半径就为屏幕的一半,代码如下所示。

        Paint painCircle = new Paint();painCircle.setColor(Color.RED);painCircle.setStyle(Paint.Style.STROKE);painCircle.setAntiAlias(true);painCircle.setStrokeWidth(5);canvas.drawCircle(mWidth/2,mHeight/2,mWidth/2,painCircle);

下面画刻度线,这个也很简单,一条线而已,只需要确定线段两个端点的坐标就可以了。第一根线还还比较简单,坐标非常容易确定。可后面的问题就来了,那些斜着的线的端点坐标无法通过简单的坐标加减来获得,必须通过角度来计算三角偶数用个遍才能算出这些点的坐标。不仅运输量大,而且非常容易出错,这当然也是非常满意接受的。所以我们来看看Android是如何简化这些运算的。

从图一中可以看出,我们之所以感觉不好画,就是因为那恶心的角度。那么如果将画布已圆心为原点为原点旋转到需要的角度呢?当灭画好一根线,就旋转相应的角度。虽然下一次画线的时候,依然是第一根线的坐标,但是实际上当我们把画布重新还原当选择前的位置时,所有的刻度就已经全部画好了。通过旋转画布——实际上是旋转了画图的坐标系,这就避免了进行复杂的三角偶数运算。通过这的相对论的变换,间接简化了绘图,这样在去绘制这些刻度线,就只需要区别整点与非整点刻度线就可以了,代码如下所示。

        Paint paintDegree = new Paint();paintDegree.setColor(Color.RED);painCircle.setStrokeWidth(3);for (int i =0;i<24;i++){if (i==0||i==6||i==12||i==18){paintDegree.setStrokeWidth(5);paintDegree.setTextSize(30);canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+60,paintDegree);String degree = String.valueOf(i);canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+90,paintDegree);}else {paintDegree.setStrokeWidth(3);paintDegree.setTextSize(15);canvas.drawLine(mWidth/2,mHeight/2-mWidth/2,mWidth/2,mHeight/2-mWidth/2+30,paintDegree);String degree = String.valueOf(i);canvas.drawText(degree,mWidth/2-paintDegree.measureText(degree)/2,mHeight/2-mWidth/2+60,paintDegree);}canvas.rotate(15,mWidth/2,mHeight/2);}

最后来画那两根指针。同样只是简单地画两个线段而已,只要算好起始点的坐标就可以了。起点自然是圆心,终点就是在圆心的坐标基础上的加减。但前面介绍了rotate()方法,那么自然也不能亏待了translate()方法。所以,我们通过画这两根指针来看看如何使用translat()方法。在前文中,我们讲了translate()方法用来平移坐标原点,将其从(0,0)的位置上移动到新的坐标。这个新的坐标自然是能够帮助我们简化绘图的坐标。那么通过translate()方法将原点移动到原点,这样再画线段的时候就可以理解为从原点开始画一条线段了。使用translate()方法,代码如下所示。

        Paint paintHour = new Paint();paintHour.setColor(Color.RED);paintHour.setStrokeWidth(20);Paint paintMinute = new Paint();paintMinute.setColor(Color.RED);paintMinute.setStrokeWidth(10);canvas.save();canvas.translate(mWidth/2,mHeight/2);canvas.drawLine(0,0,100,100,paintHour);canvas.drawLine(0,0,100,200,paintMinute);canvas.restore();

最后绘图的效果就和图(1)所示的一样了。

二、Layer图层

Andriud中的绘图API,很大程度上都来自与现实生活中的绘图,特别是借鉴了很多Photoshop中的概念,比如图层概念。那么什么是图层呢?相信用过Photoshop的朋友一定会非常清楚,一张复杂的图可以很多个图层叠加起来,形成一个复杂的图像。在Android中,使用saveLayer()方法来创建一个图层,图层同样是基于栈的结构进行管理的,如图(2)所示。

(2)图层的栈管理结构

Android通过调用saveLayer()方法、savaLayerAlpha()方法将一个图层入栈,使用restore()方法、restoreToCount()方法将一个图层出栈。入栈的时候,后面所有的操作都发生在这个图层上,而出栈的时候,则会把图像绘制到上层。下面我么就仿照API Demos里面的一个示例来看看该如何使用Layer,代码如下所示。

        Paint mPaint = new Paint();canvas.drawColor(Color.WHITE);mPaint.setColor(Color.BLUE);canvas.drawCircle(150,150,100,mPaint);canvas.saveLayerAlpha(0,0,400,400,127,0);mPaint.setColor(Color.RED);canvas.drawCircle(200,200,100,mPaint);canvas.restore();

在onDraw方法中绘制两个相交的圆,当然这个两个圆位于两个图层上。

接下来,将后面的图层透明度设置为0~255不同的数组值,看看不同的透明值效果有何不同。

当透明度为127是,即半透明,效果如图(3)所示。

当透明度为255时,即完全不透明,效果如图(4)所示。

当透明度为0时,即完全透明,效果如图(5)所示。

    

(3)                                                  (4)                                                     (5)

Android 绘图技巧相关推荐

  1. Android绘图机制与处理技巧-更新中

    概述 这里我们主要来探讨下 Android屏幕的相关只是 Android绘图技巧 Android图像处理技巧 SurfaceView的使用 绘图技巧中,医生讲的比较粗略,更多的细节参考了 Keegan ...

  2. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧...

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息 屏幕大小:屏幕对角线长度,单位"寸": 分辨率:手机屏幕像素点个数,例如720x1280分辨率: PPI(Pixels ...

  3. 第六章Android绘图机制与处理技巧(Android群英传)

    本章将介绍关于Andorid绘图机制的一些高级技巧与分析 6.1.屏幕的尺寸信息 一般我们以720x1280为标准原稿,那么1dp = 2px 6.2.2D绘图基础 Canvas提供了很多api 如: ...

  4. Android绘图(四)阴影、渐变和位图运算处理

    目录 一.阴影 1.1 案例-为文字添加阴影和发光效果 二. 渐变 2.1 线性渐变(LinearGradient) 2.1.1 案例- 实现圆角矩形环形渐变 2.2 径向渐变(RadialGradi ...

  5. android 绘画,Android绘图基础

    绘图三要素 一支画笔 Paint. 一张画布 Canvas. 一个 Bitmap 或者一个 View 来承载这个图形. Paint常用属性 setAntiAlias() 设置画笔锯齿效果. setCo ...

  6. Android实战技巧之十一:Android Studio和Gradle

    2019独角兽企业重金招聘Python工程师标准>>> 经过两个多月的AS体验,我认为是时候将Android的开发环境迁移到AS上了.目前最新版本是1.0.2(大年30当天升级到1. ...

  7. android 绘图之Canvas,Paint类

    Canvas,Paint 1.在android 绘图但中经常要用到Canvas和Paint类,Canvas好比是一张画布,上面已经有你想绘制图画的轮廓了,而Paint就好比是画笔,就要给Canvas进 ...

  8. Android开发技巧——大图裁剪

    本篇内容是接上篇<Android开发技巧--定制仿微信图片裁剪控件> 的,先简单介绍对上篇所封装的裁剪控件的使用,再详细说明如何使用它进行大图裁剪,包括对旋转图片的裁剪. 裁剪控件的简单使 ...

  9. Android开发技巧——自定义控件之自定义属性

    Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个 ...

最新文章

  1. 腾讯AI种番茄双丰收:参赛AI全胜专家,辽宁试点净利增千元
  2. How do annotations work internally--转
  3. java mysql查询界面_Java GUI小程序 实现数据库查询界面-Go语言中文社区
  4. 设置熄屏_华为手机熄屏后还能这样操作?你不知道就挺遗憾的!
  5. Oracle中RAISE异常详解
  6. 使用promise封装ajax
  7. Django死活不跳转的问题
  8. 网站QQ全屏PHP代码,QQ技术导航升级版 超级导航美化版带后台版 PHP源码
  9. 程序员的算法课(5)-动态规划算法
  10. SpringBoot基础教程1-1-2 配置文件介绍
  11. lidar与相机联合标定开源软件介绍
  12. 【UVA514】+【HDOJ1022]:出栈序列的可能性问题
  13. android 4.4 生僻字,Android上显示生僻字的方法
  14. 2022年信息学奥赛介绍
  15. 基于turtle库用python画太极图案
  16. 华为云存储服务分享文件的方法
  17. 五大最受欢迎的BUG管理系统 .
  18. 关于SYSTICK延时函数的两个小疑问
  19. ROS基础篇(二)-- 基础知识
  20. stm32f103c8t6与stm32f103zet6 基于SX1276串口通信-----发送端(二)

热门文章

  1. UIImageView 等比缩放显示
  2. 使用GraphQL,React Native和AWS AppSync编写应用程序代码:后端
  3. Adobe PS 2021版本的Photoshop出来啦
  4. 个性化推荐从入门到精通
  5. 磨金石教育摄影技能干货分享|曾毅——尘封的故土,难忘的乡愁
  6. linux tomcat设置classpath,理解Tomcat的Classpath-常见问题以及如何解决
  7. EM加血程序(多人版)程序(流星程序集之六)
  8. 清理磁盘Linux命令
  9. Chrome谷歌浏览器首页被改为Hao123导航怎么办
  10. 安装特定版本的keras_Win10上安装Keras 和 TensorFlow(GPU版本)