利用Canvas 的 drawXXX() 方法配合 Paint 的几个常用方法可以实现最常见的绘制需求;而如果你只会基本的绘制, Paint 的完全功能的掌握,能让你更进一步,做出一些更加细致、炫酷的效果。把 Paint 掌握之后,你几乎不再会遇到「iOS 组可以实现,但你却实现不了」的绘制效果。
好,下面进入正题。
Paint 的 API 大致可以分为 4 类:
- 颜色
- 效果
- drawText() 相关
- 初始化
下面我就对这 4 类分别进行介绍:
1 颜色Canvas 绘制的内容,有三层对颜色的处理:
1.1基本颜色Paint 设置颜色的方法有两种:一种是直接用 Paint.setColor/ARGB() 来设置颜色,另一种是使用 Shader 来指定着色方案。
1.1.1直接设置颜色
方法名和使用方法都非常简单直接,不再多说。
paint.setColor(Color.parseColor("#CCFBFF"));
canvas.drawCircle(400, 450, 300, paint);
然后,setARGB(int a, int r, int g, int b)其实和 setColor(color) 都是一样的,只是它的参数用的是更直接的三原色与透明度的值。实际运用中,setColor() 和 setARGB() 哪个方便和顺手用哪个吧。
setShader(Shader shader) 设置 Shader
除了直接设置颜色,Paint还可以使用Shader。
Shader不是 Android 独有的,它是图形领域里一个通用的概念,它和直接设置颜色的区别是,它设置的是一套颜色方案,或者说是一套着色规则。当设置了 Shader 之后,Paint 在绘制图形和文字时就不使用 setColor/ARGB() 设置的颜色了,而是使用 Shader 的方案中的颜色。
在 Android 的绘制里使用 Shader ,并不直接用 Shader 这个类,而是用它的几个子类。具体来讲有 LinearGradient RadialGradient SweepGradient BitmapShader ComposeShader 这么几个:
LinearGradient 线性渐变
设置两个点和两种颜色,以这两个点作为端点,使用两种颜色的渐变来绘制颜色。就像这样:
构造方法:
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) 。
参数:
x0 y0 x1 y1:渐变的两个端点的位置
color0 color1 是端点的颜色
tile:端点范围之外的着色规则,类型是 TileMode。TileMode 一共有 3 个值可选: CLAMP, MIRROR 和 REPEAT。CLAMP 会在端点之外延续端点处的颜色;MIRROR 是镜像模式;REPEAT 是重复模式。具体的看一下例子就明白。
CLAMP:
MIRROR:
REPEAT:
RadialGradient 辐射渐变
辐射渐变很好理解,就是从中心向周围辐射状的渐变。大概像这样:
构造方法:
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)。
参数:
centerX centerY:辐射中心的坐标
radius:辐射半径
centerColor:辐射中心的颜色
edgeColor:辐射边缘的颜色
tileMode:辐射范围之外的着色模式(跟LinearGradient的差不多就不细写了)。
SweepGradient 扫描渐变
这个渐变就是从某个角度开始进行360度的颜色渐变。大概就是这样:
构造方法:
SweepGradient(float cx, float cy, int color0, int color1)
参数:
cx cy :扫描的中心
color0:扫描的起始颜色
color1:扫描的终止颜色
BitmapShader
用 Bitmap 来着色。其实也就是用 Bitmap 的像素来作为图形或文字的填充。大概像这样:
构造方法:
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
参数:
bitmap:用来做模板的 Bitmap 对象
tileX:横向的 TileMode
tileY:纵向的 TileMode。
CLAMP:
MIRROR:
REPEAT:
ComposeShader 混合着色器
所谓混合,就是把两个 Shader 一起使用。我把小鸡跟小溪拼到了一起,大概就是这样:
注意:上面这段代码中我使用了两个 BitmapShader 来作为 ComposeShader() 的参数,而 ComposeShader() 在硬件加速下是不支持两个相同类型的 Shader 的,所以这里也需要关闭硬件加速才能看到效果。
构造方法:ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
参数:
shaderA, shaderB:两个相继使用的 Shader
mode: 两个 Shader 的叠加模式,即 shaderA 和 shaderB 应该怎样共同绘制。它的类型是 PorterDuff.Mode 。
PorterDuff.Mode
PorterDuff.Mode 是用来指定两个图像共同绘制时的颜色策略的。它是一个 enum,不同的 Mode 可以指定不同的策略。「颜色策略」的意思,就是说把源图像绘制到目标图像处时应该怎样确定二者结合后的颜色,而对于 ComposeShader(shaderA, shaderB, mode) 这个具体的方法,就是指应该怎样把 shaderB 绘制在 shaderA 上来得到一个结合后的 Shader。
对于这些 Mode,正确的做法是:对于 Alpha 合成类的操作,掌握他们,并在实际开发中灵活运用;而对于混合类的,你只要把它们的名字记住就好了,这样当某一天设计师告诉你「我要做这种混合效果」的时候,你可以马上知道自己能不能做,怎么做。
另外:PorterDuff.Mode 建议你动手用一下试试,对加深理解有帮助。
好了,今天就是几个 Shader 的具体介绍。
除了使用 setColor/ARGB() 和 setShader() 来设置基本颜色, Paint 还可以来设置 ColorFilter,来对颜色进行第二层处理,这个内容就留到下次讲,祝大家都能越来越优秀!



