一、阴影:
Paint 类定义了一个名为 setShadowLayer 的方法:
public void
setShadowLayer(float radius,float dx,float dy,int shadowColor), 参数意义如下:
radius:阴影半径
dx: x 方向阴影的偏移量
dy: y 方向阴影的偏移量
shadowColor: 阴影的颜色
阴影layer显示 影时,shaderlayer 有 两 种 类 型 : View.LAYER_TYPE_SOFTWARE 和View.LAYER_TYPE_HARDWARE, layer 的默认类型为 LAYER_TYPE_HARDWARE, 但阴影只能在
View.LAYER_TYPE_SOFTWARE 环 境 下 工 作 , 所 以 , 我 们 需 要 调 用 View 类 的 publicvoid
setLayerType(int layerType,Paint paint) 方 法 为 Paint 对 象 指 定 层 的 类 型 :
setLayerType(View.LAYER_TYPE_SOFTWARE, paint)。如想取消阴影则将radius设置为0.
ShaderView.java:
public class ShaderView extends View { private Paint paint; public ShaderView(Context context, AttributeSet attrs) { super(context, attrs); } public ShaderView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(5); paint.setTextSize(100); this.setLayerType(View.LAYER_TYPE_SOFTWARE,paint);//设置为SOFTWARE才会实现阴影 paint.setShadowLayer(10,1,1, Color.BLUE);//偏移度很小时则变成发光字体 canvas.drawText("Android开发",100,100,paint); canvas.restore(); paint.setShadowLayer(10,5,5,Color.GREEN);//如果想要取消阴影,则将Radius设为0即可 canvas.drawText("Android,你好",100,400,paint); } }
二、渐变
渐变种类有:
1. 线性渐变: LinearGradient
线性渐变( LinearGradient) 根据指定的角度、颜色和模式使用渐变颜色填充绘图区域。我们必须定义两个点( x0, y0)和( x1, y1),渐变的方向与这两个点的连线垂直,
LinearGradient 的构造方法如下:
<1>
public LinearGradient(float x0,float y0,float x1,float y1,int color0,int color1,TileMode tile):本方法用于两种颜色的渐变, 各参数意义如下:
x0、 y0: 用于决定线性方向的第一个点的坐标( x0, y0);
x1、 y1:用于决定线性方向的第二个点的坐标( x1, y1);
color0: 第一种颜色;
color1: 第二种颜色;
tile: 渐变模式
<2>
public LinearGradient(float x0,float y0,float x1,floaty1,int colors[],float positions[],TileMode tile), 这是一个功能更加强大的构造方法, 我们来看看该构造方法参数的作用:
x0、 y0:起始点的坐标
x1、 y1:终止点的坐标
colors:多种颜色
positions:颜色的位置(比例)
TileMode:渐变模式
参数 colors 和 positions 都是数组, 前者用于指定多种颜色,后者用于指定每种颜色的起始比例位置。 positions 数组中的元素个数与 colors 要相同, 且是 0 至 1 的数值, [0,1]是临界区,
如果小于 0 则当 0 处理, 如果大于 1 则当 1 处理。假如在绘图区域和渐变区域大小相同的情况下,colors 包含了三种颜色: red、 yellow、 green, 在渐变区域中这三种颜色的起始比例位置为 0、 0.3、
2. 径向渐变: RadialGradient
径向渐变是以指定的点为中心, 向四周以渐变颜色进行圆周扩散, 和线性渐变一样,支持两种或多种颜色。
<1>public RadialGradient(float x,floaty,float
radius,int color0,int
color1,TileMode tile), 该构造方法支持两种颜色, 下面是参数的作用:
x、 y: 中心点坐标
radius: 渐变半径
color0:起始颜色
color1:结束颜色
TileMode:渐变模式
<2>public RadialGradient(float x,floaty,float
radius,int colors[],float positions[],
TileModetile), 该构造方法支持 3 种或 3 种以上颜色的渐变, 各参数的作用如下:
x、 y: 中心点坐标
radius: 渐变半径
colors:多种颜色
positions:颜色的位置(比例)
TileMode:渐变模式
构造函数2用法如上;
3. 扫描渐变: SweepGradient
SweepGradient 类似于军事题材电影中的雷达扫?效果, 固定圆心, 将半径假想为有形并旋
转一周而绘制的渐变颜色。 SweepGradient 定义了两个主要的构造方法:
<1>public SweepGradient(float cx,float cy,int color0,int color1)
支持两种颜色的扫描渐变, 参数的作用如下:
cx、 cy:圆点坐标;
color0:起始颜色;
color1:结束颜色。
<2>public SweepGradient(float cx,float cy,int colors[],float positions[])
支持多种颜色的扫描渐变, 参数的作用如下:
cx、 cy:圆点坐标;
colors:多种颜色;
positions:颜色的位置(比例)。
4. 位图渐变: BitmapShader
位图渐变其实就是在绘制的图形中将指定的位图作为背景, 如果图形比位图小, 则通过渐变模式进行平铺, TileMode.CLAMP 模式不平铺, TileMode.REPEAT 模式表示平铺, TileMode.MIRROR
模式也表示平铺, 但是交错的位图是彼此的镜像, 方向相反。 可以同时指定水平和垂直两个方向的渐变模式。
构造方法:
public BitmapShader(Bitmap bitmap,TileMode tileX,TileMode tileY), 参数如下:
bitmap:位图;
tileX: x 方向的重复模式;
tileY: y 方向的重复模式。
5. 混合渐变: ComposeShader
混合渐变 ComposeShader是将两种不同的渐变通过位图运算后得到的一种更加复杂的渐变。
构造方法:
<1>public ComposeShader(Shader shaderA,Shader shaderB,Xfermode mode)
<2>public ComposeShader(Shader shaderA,Shader shaderB,Mode mode)
shaderA 和 shaderB 是两个渐变对象, mode 为位图运算类型, 16 种运算模式如图 5-15
所示:
代码中, shaderA 为位图渐变, shaderB 为线性渐变, 根据 Mode.SRC_ATOP 的运算规则,
shaderA 会全部显示( 此处为小机器人), shaderB 只显示二者相交部分并位于最上面( TOP)。
渐变效果代码:
public class RadialGradientView extends View { private int color[]={Color.GREEN,Color.BLUE,Color.RED}; //private float position[]={0,0.5f,1}; public RadialGradientView(Context context, AttributeSet attrs) { super(context, attrs); } public RadialGradientView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Rect rect=new Rect(100,100,600,600); //1.径向渐变 RadialGradient r=new RadialGradient(350,350,250, Color.BLUE,Color.YELLOW, Shader.TileMode.MIRROR); //2.线性渐变 // LinearGradient r=new LinearGradient(100,100,600,600,Color.RED,Color.GREEN, Shader.TileMode.CLAMP); //3.扫描渐变 // SweepGradient r=new SweepGradient(350,350,Color.RED,Color.GREEN); //SweepGradient r=new SweepGradient(350,350,color,null); //4.位图渐变 // Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.boy); // BitmapShader r=new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR); //5.混合渐变 // LinearGradient lg=new LinearGradient(100,100,600,600,Color.RED,Color.GREEN, Shader.TileMode.CLAMP); // Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.boy); // BitmapShader bs=new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR); // ComposeShader r=new ComposeShader(bs,lg, PorterDuff.Mode.SRC_ATOP); //公用部分 Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG); paint.setShader(r); canvas.drawRect(rect,paint); canvas.translate(0,500); canvas.drawOval(new RectF(rect),paint); } }
渐变与Matrix
public void setLocalMatrix(Matrix localM), 该方法能和渐变结合,在填充渐变颜色的时候实现移位、旋转、缩放和拉斜的效果。
我们做一个旋转的圆, 圆内使用 SweepGradient 渐变填充,看起来像一张光盘。首先, 我们创建了一个 Matrix 对象 mMatrix, mMatrix 定义了以圆点为中心渐变的旋转效
果, 注意不是旋转 Canvas 而是旋转 SweepGradient。 onDraw()方法中不断调用 invalidate()重绘自己, 每重绘一次就旋转 2 度,于是就形成了一个旋转的动画。
SweepMatrixView.java:
public class SweepMatrixView extends View { private Paint mpaint=new Paint(Paint.ANTI_ALIAS_FLAG); private float mRotate; private Matrix matrix=new Matrix(); private Shader mshader; private int[] color={ Color.GREEN,Color.RED,Color.BLUE}; public SweepMatrixView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(true); setFocusableInTouchMode(true); float x=100; float y=100; mshader=new SweepGradient(x,y,color,null); mpaint.setShader(mshader); } public SweepMatrixView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint =mpaint; float x=100; float y=100; canvas.translate(100,100); canvas.drawColor(Color.WHITE); matrix.setRotate(mRotate,x,y); mshader.setLocalMatrix(matrix); mRotate+=2; if(mRotate>=360){ mRotate=0; } invalidate(); canvas.drawCircle(x,y,100,paint); } }
可以实现扫描渐变像光盘一样旋转。