前言
根据启舰大大 的博客所学习的自定义View。
一、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)
- (centerX ,centerY):渐变中心点坐标(x,y)
- radius:渐变半径
- centerColor:渐变的起始颜色,即渐变中心点的颜色,取值类型必须是八位的0xAARRGGBB色值!透明底Alpha值不能省略,不然不会显示出颜色。
- edgeColor:渐变结束时的颜色,即渐变圆边缘的颜色,同样,取值类型必须是八位的0xAARRGGBB色值!
- TileMode:与我们前面讲的各个Shader一样,用于指定当控件区域大于指定的渐变区域时,空白区域的颜色填充方式。
二、小试牛刀
//多色渐变
int[] colors = new int[]{0xffff0000,0xff00ff00,0xff0000ff,0xffffff00};
float[] stops = new float[]{0f,0.4f,0.6f,1f};
paint.setShader(new RadialGradient(100,100,50,colors,stops, Shader.TileMode.CLAMP));
canvas.drawCircle(100,100,100,paint);
//双色渐变
paint.setShader(new RadialGradient(300,300,50,0xffff0000, 0xff0000ff,Shader.TileMode.MIRROR));
canvas.drawCircle(300,300,150,paint);
效果图
ps:看着第二个镜像是不是有点晕呢?嘿嘿,我也晕了,其实是由红变蓝,再由蓝变红,再由红变蓝......这样子继续下去,白色的那条线就是每一圈渐变的边界,(⊙o⊙)…有点不清晰,大家可以自己画个大大的圆试试
三、水波纹效果
先看效果图吧
水波纹效果源码如下:
public class MineView extends View {
private Paint paint;
float radius;
ValueAnimator animator;
int width; //控件的宽度
int x, y; //当前触摸点的位置
public MineView(Context context) {
this(context, null);
}
public MineView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//在这可以获取控件宽度,不要在初始化的时候获取,那时候是获取不到的
width = getMeasuredWidth();
animator = ValueAnimator.ofInt(50, width);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
radius = (int) animation.getAnimatedValue();
updateShader();
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
radius = 0;
updateShader();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
canvas.drawColor(Color.LTGRAY);
canvas.drawCircle(x, y, radius, paint);
}
private void updateShader() {
if (x > 0 && y > 0 && radius > 0) {
//从零透明度逐渐变为绿色
RadialGradient radialGradient = new RadialGradient(x, y, radius, 0x00FFFFFF, 0xFF00FF00, Shader.TileMode.CLAMP);
paint.setShader(radialGradient);
}
postInvalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (x != event.getX() || y != event.getY()) {
x = (int) event.getX();
y = (int) event.getY();
radius = 50;
updateShader();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_UP:
if (animator != null) {
if (animator.isRunning()) animator.cancel();
animator.start();
}
break;
}
return super.onTouchEvent(event);
}
}
小知识
getMeasureWidth()方法在measure()过程结束后就可以获取到了,
而getWidth()方法要在layout()过程结束后才能获取到
网友评论