阴影和渐变
阴影
可以为文字和图形指定阴影。在绘图中,有一个叫做layer(层)的概念。默认情况下,我们的文字和图形绘制在主层(main layer)上,其实也可以将内容绘制在新建的layer上。实际上阴影就是在main layer的下面添加了一个阴影层(shader layer),可以为阴影指定模糊度、偏移量和阴影颜色。
Paint类定义了一个名为setShadowLayer()的方法,如下:
//radius:阴影半径;
//dx:x方向阴影的偏移量;
//dy:y方向阴影的偏移量;
//shadowColor:阴影的颜色;
public void setShadowLayer(float radius, float dx, float dy, int shadowColor)
阴影layer显示阴影时,shader layer有两种类型:View.LAYER_TYPE_SOFTWARE和View.LAYER_TYPE_HARDWARE,layer的默认类型为LAYER_TYPE_HARDWARE,但阴影只能在View.LAYER_TYPE_SOFTWARE环境下工作,所以,我们需要调用View类的setLayerType()方法为Paint对象指定层的类型,即setLayerType(View.LAYER_TYPE_SOFTWARE,paint)。
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(100);
this.setLayerType(View.LAYER_TYPE_SOFTWARE,paint);
paint.setShadowLayer(10,1,1,Color.RED);
canvas.drawText("Android开发测试",100,100,paint);
上面代码中,我们使用paint.setShadowLayer(10,1,1,Color.RED)这一句定义了一个模糊半径为10,x方向和y方向偏移量都为1的红色阴影。当偏移量足够小时,效果可以认为是发光效果。当偏移量比较大的时候,就可以看到阴影效果了。
一旦定义了阴影层,接下来所有的绘制都会带阴影效果了。如果想取消阴影,将setShadowLayer()方法的radius参数设置为0即可。但是先前应用了阴影的效果还在,只是接下来不再受阴影的影响了。
渐变
渐变是绘图过程中颜色或位图以特定规律进行变化。
渐变种类有如下:
1 . 线性渐变:LinearGradient;
2 . 径向渐变:RadialGradient;
3 . 扫描渐变:SweepGradient;
4 . 位图渐变:BitmapShader;
5 . 混合渐变:ComposeShader;
其中,线性渐变、径向渐变、扫描渐变属于颜色渐变,指定2种或2种以上的颜色,根据颜色过渡算法自动计算出中间的过渡颜色,从而形成渐变效果。位图渐变则不再是简单的颜色渐变,而是以图片做为贴片有规律的变化,类似于壁纸平铺。混合渐变则能将多种渐变进行组合,实现更加复杂的渐变效果。
如果A、B分别代表两种不同的颜色,我们将渐变分为三种,如下:
1 . ABAB型:A、B两种颜色重复变化,通过TileMode类的REPEAT常量来表示;
2 . ABBA型:A、B两种颜色镜像变化,通过TileMode类的MIRROR常量来表示;
3 . AABB型:A、B两种颜色只出现一次,通过TileMode类的CLAMP常量来表示;
定义渐变时,必须指定一个渐变区域,根据定义的渐变内容和渐变模式填满该区域。每一种渐变被定义为一个类,他们都继承自同一个父类--Shader。绘图时,调用Paint类的setShader()方法指定一种渐变类型,绘制出来的绘图填充区域都将使用指定的渐变颜色或位图进行填充。
TileMode是Shader类中的内部枚举类,如下:
public static enum TileMode {
CLAMP,
MIRROR,
REPEAT;
private TileMode() {
}
}
讨论渐变时,虽然一般是指填充区域的渐变,但绘图样式为STROKE时,线条同样可以使用渐变效果。
线性渐变
线性渐变(LinearGradient)根据指定的角度、颜色和模式使用渐变颜色填充绘图区域。我们必须定义两个点(x0,y0)和(x1,y1),渐变的方向与这两个点的连线垂直。
//x0、y0:用于决定线性方向的第一个点的坐标(x0,y0);
//x1、y1:用于决定线性方向的第二个点的坐标(x1,y1);
//color0:第一种颜色;
//color1:第二种颜色;
//tile:渐变模式;
public LinearGradient(float x0, float y0, float x1, float y1,
@ColorInt int color0,
@ColorInt int color1,
@NonNull TileMode tile)
Rect rect1 = new Rect(100, 100, 500, 400);
LinearGradient lg = new LinearGradient(rect1.left, rect1.top, rect1.right, rect1.bottom, Color.RED, Color.BLUE, Shader.TileMode.CLAMP);
paint.setShader(lg);
canvas.drawRect(rect1, paint);
如果两种颜色无法满足绘图需求,LinearGradient也支持三种及三种以上颜色的渐变,也就是另一种构造方法,如下:
//x0、y0:起始点的坐标;
//x1、y1:终止点的坐标;
//colors:多种颜色;
//positions:颜色的位置(比例);
//TileMode:渐变模式;
public LinearGradient(float x0, float y0, float x1, float y1,
@NonNull @ColorInt int colors[],
@Nullable float positions[],
@NonNull TileMode tile)
参数colors和positions都是数组,前者用于指定多种颜色,后者用于指定每种颜色的起始比例位置。positions数组中的元素个数要与colors数组中的个数相同,且是0至1的数值,[0,1]是临界区,如果小于0则当0处理,如果大于1则当1处理。
径向渐变
径向渐变是以指定的点为中心,向四周以渐变颜色进行圆周扩散,和线性渐变一样,支持两种或多种颜色。
径向渐变的两种构造方法如下:
//该构造方法支持两种颜色;
//x、y:中心点坐标;
//radius:渐变半径;
//color0:起始颜色;
//color1:结束颜色;
//TileMode:渐变模式;
public RadialGradient(float centerX, float centerY, float radius,
@ColorInt int centerColor,
@ColorInt int edgeColor,
@NonNull TileMode tileMode)
//该构造方法支持三种及三种以上颜色的渐变;
//x、y:中心点坐标;
//radius:渐变半径;
//colors:多种颜色;
//positions:颜色的位置(比例);
//TileMode:渐变模式;
public RadialGradient(float centerX, float centerY, float radius,
@NonNull @ColorInt int colors[],
@Nullable float stops[],
@NonNull TileMode tileMode)
Rect rect = new Rect(100, 100, 500, 500);
RadialGradient rg = new RadialGradient(300, 300, 200, Color.RED, Color.GREEN, Shader.TileMode.MIRROR);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setShader(rg);
canvas.drawRect(rect, p);
扫描渐变
SweepGradient类似于雷达扫描效果,固定圆心,将半径假想为有形并旋转一周而绘制的渐变颜色。SweepGradient的两个构造方法,如下:
//该方法支持两种颜色的扫描渐变;
//cx、cy:圆点坐标;
//color0:起始颜色;
//color1:结束颜色;
public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1)
//支持多种颜色的扫 渐变;
//cx、cy:圆点坐标;
//colors:多种颜色;
//positions:颜色的位置(比例);
public SweepGradient(float cx, float cy,@NonNull @ColorInt int colors[], @Nullable float positions[])
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
SweepGradient sg = new SweepGradient(300, 300, Color.GREEN, Color.YELLOW);
paint.setShader(sg);
canvas.drawRect(new Rect(0, 0, 600, 600), paint);
位图渐变
位图渐变其实就是在绘制的图形中将指定的位图做为背景,如果图形比位图小,则通过渐变模式进行屏幕,TileMode.CLAMP模式不平铺,TileMode.REPEAT模式表示平铺,TileMode.MIRROR模式也表示平铺,但是交错的位图是彼此的镜像,方向相反。可以同时指定水平和垂直两个方向的渐变模式。
BitmapShader只有一个构造方法,如下:
//bitmap:位图;
//tileX:x 方向的重复模式;
//tileY:y 方向的重复模式;
public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY)
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
BitmapShader bs = new BitmapShader(bmp,Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(bs);
canvas.drawRect(new Rect(0, 0,getMeasuredWidth(), getMeasuredHeight()), paint);
混合渐变
混合渐变ComposeShader是将两种不同的渐变通过位图运算后得到的一种更加复杂的渐变。位图运算有16种方法。
ComposeShader有两个构造方法,如下:
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull PorterDuff.Mode mode)
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode)
shaderA和shaderB是两个渐变对象,mode为位图运算类型。
渐变与Matrix
渐变类都继承自同一个类--Shader,该类并不复杂,不过定义了一个方法:setLocalMatrix(Matrix matrix),该方法能和渐变结合,在填充渐变颜色的时候实现移位、旋转、缩放和拉斜的效果。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----------------------last line for now----------------------