我们在用Android中的Canvas绘制各种图形时,可以通过Paint.setShader(shader) 方法为画笔Paint设置shader,这样就可以绘制出多彩的图形。那么Shader是什么呢?做过GPU绘图的同学应该都知道这个词汇,Shader就是着色器的意思。我们可以这样理解,Canvas中的各种drawXXX方法定义了图形的形状,画笔中的Shader则定义了图形的着色、外观,二者结合到一起就决定了最终Canvas绘制的被色彩填充的图形的样子。 类 android.graphics.Shader 有五个子类,分别是:BitmapShader、LinearGradient、RadialGradient、SweepGradient和ComposeShader,下面依次对这几个类的使用分别说明。 BitmapShaderBitmapShader,顾名思义,就是用Bitmap对绘制的图形进行渲染着色,其实就是用图片对图形进行贴图。 BitmapShader构造函数如下所示: BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY) 第一个参数是Bitmap对象,该Bitmap决定了用什么图片对绘制的图形进行贴图。 第二个参数和第三个参数都是Shader.TileMode类型的枚举值,有以下三个取值:CLAMP 、REPEAT 和 MIRROR。
最后需要说的是,在构造BitmapShader时,tileX和tileY可以取不同的值,二者不用非得一致。 LinearGradient我们可以用LinearGradient创建线性渐变效果,其有两个构造函数: LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile) 我们重点说一下第一个构造函数,在此基础上理解第二个构造函数就很简单了。 LinearGradient是用来创建线性渐变效果的,它是沿着某条直线的方向渐变的,坐标(x0,y0)就是这条渐变直线的起点,坐标(x1,y1)就是这条渐变直线的终点。需要说明的是,坐标(x0,y0)和坐标(x1,y1)都是Canvas绘图坐标系中的坐标。color0和color1分别表示了渐变的起始颜色和终止颜色。与BitmapShader类似,LinearGradient也支持TileMode,有以下三个取值:CLAMP 、REPEAT 和 MIRROR。 使用代码如下所示: LinearGradient linearGradient = new LinearGradient(100, 100, 500, 500, Color.GREEN, Color.BLUE, Shader.TileMode.CLAMP); paint.setShader(linearGradient); canvas.drawRect(100, 100, 500, 500, paint); 效果如下所示: 上面我们使用了CLAMP,但是由于我们绘制的矩形与渐变位置的大小一样大,所以CLAMP效果不明显。 我们把绘制的区域变大,还是用CLAMP,这次绘制整个Canvas大小的矩形。 canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint); 效果如下所示: 当我们把CLAMP改为REPEAT时,还是绘制整个Canvas大小的矩形,效果如下所示: 当我们用MIRROR绘制整个Canvas大小的矩形的时候,效果如下所示: 在LinearGradient的第二个构造函数中可以通过参数colors传入多个颜色值进去,这样就会用colors数组中指定的颜色值一起进行颜色线性插值。还可以指定positions数组,该数组中每一个position对应colors数组中每个颜色在线段中的相对位置,position取值范围为[0,1],0表示起始位置,1表示终止位置。如果positions数组为null,那么Android会自动为colors设置等间距的位置。 RadialGradient我们可以用RadialGradient创建从中心向四周发散的辐射渐变效果,其有两个构造函数: RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode) RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode) 这两个构造函数和LinearGradient的两个构造函数很类似,我们此处还是重点讲解第一个构造函数,在此基础上理解第二个构造函数就很简单了。 RadialGradient是用来创建从中心向四周发散的辐射渐变效果的,所以我们需要在其构造函数中传入一些圆的参数,坐标(centerX,centerY)是圆心,即起始的中心颜色的位置,radius确定了圆的半径,在圆的半径处的颜色是edgeColor,这样就确定了当位置从圆心移向圆的轮廓时,颜色逐渐从centerColor渐变到edgeColor。RadialGradient也支持TileMode参数,有以下三个取值:CLAMP 、REPEAT 和 MIRROR。 我们首先将CLAMP作为TileMode,代码如下所示: int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); float centerX = canvasWidth / 2f; float centerY = canvasHeight / 2f; float radius = canvasWidth / 4f; RadialGradient radialGradient = new RadialGradient(centerX, centerY, radius, Color.GREEN, Color.BLUE, Shader.TileMode.MIRROR); paint.setShader(radialGradient); canvas.drawRect(0, 0, canvasWidth, canvasHeight, paint); 效果如下所示:
在上图中,我们绘制的矩形和Canvas大小一样大,其尺寸大于我们定义的RadialGradient的圆的尺寸。我们可以看到,当使用CLAMP作为TileMode时,颜色从圆心的绿色向圆周的蓝色渐变,在圆以外的空间都用edgeColor蓝色填充。 |