前言:每当感叹自己的失败时,那我就问你,如果让你重新来一次,你会不会成功?如果会,那说明并没有拼尽全力。
系列文章:
Android自定义控件三部曲文章索引:http://blog.csdn.net/harvic880925/article/details/50995268
最近博主实在是太忙了,博客更新实在是太慢了,真是有愧大家。
这篇将是Shader的最后一篇,下部分,我们将讲述Canvas变换的知识。在讲完Canvas变换以后,就正式进入第三部曲啦,是不是有点小激动呢……
今天给大家讲的效果是使用RadialGradient来实现水波纹按钮效果,水波纹效果是Android L平台上自带的效果,这里我们就看看它是如何实现的,本篇的最终效果图如下
###一、RadialGradient详解
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)
(1)、两色渐变构造函数使用实例
下面我们来看一下两色渐变构造函数的使用方法。
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
这个两色渐变的构造函数的各项参数意义如下:
- centerX:渐变中心点X坐标
- centerY:渐变中心点Y坐标
- radius:渐变半径
- centerColor:渐变的起始颜色,即渐变中心点的颜色,取值类型必须是八位的0xAARRGGBB色值!透明底Alpha值不能省略,不然不会显示出颜色。
- edgeColor:渐变结束时的颜色,即渐变圆边缘的颜色,同样,取值类型必须是八位的0xAARRGGBB色值!
- TileMode:与我们前面讲的各个Shader一样,用于指定当控件区域大于指定的渐变区域时,空白区域的颜色填充方式。
下面我们举个例子来看下用法:
public class DoubleColorRadialGradientView extends View {
private Paint mPaint;
private RadialGradient mRadialGradient;
private int mRadius = 100;
public DoubleColorRadialGradientView(Context context) {
super(context);
init();
}
public DoubleColorRadialGradientView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DoubleColorRadialGradientView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
setLayerType(LAYER_TYPE_SOFTWARE,null);
mPaint = new Paint();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mRadialGradient = new RadialGradient(w/2,h/2,mRadius,0xffff0000,0xff00ff00, Shader.TileMode.REPEAT);
mPaint.setShader(mRadialGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth()/2,getHeight()/2,mRadius,mPaint);
}
}
代码量不大,这里首先在onSizeChange中,创建RadialGradient实例。onSizeChange会在布局发生改变时调用,onSizeChanged(int w, int h, int oldw, int oldh)
传过来四个参数,前两个参数就代表当前控件所应显示的宽和高。有关onSizeChange的具体意义,我们会在第三部曲讲解回调函数流程中具体讲到,这里大家就先理解到这吧。
在onSizeChange中,我们创建了一个RadialGradient,以控件的中心点为圆点,创建一个半径为mRadius的,从0xffff0000到0xff00ff00的放射渐变。我们这里指定的空白填充方式为Shader.TileMode.REPEAT。
然后在绘图的时候:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth()/2,getHeight()/2,mRadius,mPaint);
}
在绘图时,依然是以控件中心点为圆心,画一个半径为mRadius的圆;注意我们画的圆的大小与所构造的放射渐变的大小是一样的,所以不存在空白区域的填充问题。
效果图如下:
(2)、多色渐变构造函数使用实例
多色渐变的构造函数如下:
RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)
这里与两色渐变不同的是两个函数:
- int[] colors:表示所需要的渐变颜色数组
- float[] stops:表示每个渐变颜色所在的位置百分点,取值0-1,数量必须与colors数组保持一致,不然直接crash,一般第一个数值取0,最后一个数值取1;如果第一个数值和最后一个数值并没有取0和1,比如我们这里取一个位置数组:{0.2,0.5,0.8},起始点是0.2百分比位置,结束点是0.8百分比位置,而0-0.2百分比位置和0.8-1.0百分比的位置都是没有指定颜色的。而这些位置的颜色就是根据我们指定的TileMode空白区域填充模式来自行填充!!!有时效果我们是不可控的。所以为了方便起见,建议大家stop数组的起始和终止数值设为0和1.
下面我们举个例子来看下用法:
public class MultiColorRadialGradientView extends View {
private Paint mPaint;
private RadialGradient mRadialGradient;
private int mRadius = 100;
public MultiColorRadialGradientView(Context context) {
super(context);
init();
}
public MultiColorRadialGradientView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MultiColorRadialGradientView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init