Android M已经发布,但是很多机器才升级到Android L,升级到L之后我们发现很多的按钮点击的时候会有一圈波纹扩散出去的效果,炫酷到没朋友。但是不是所有的版本上都有这个效果的,怎么办呢?有大神开发出了一个nineOldAndroid的动画包,我们可以使用里面的api做自定义的开发这样就可以用到各种版本上面了。
传送门在此:
http://nineoldandroids.com/
https://github.com/JakeWharton/NineOldAndroids
我找到了这么一个图,类似于下面的效果,我只是非常简单的说下具体是怎么实现的,如果想做的更好一点请自己包装开发,只说关键代码,代码有参考下面的工程。
此图和代码的传送门https://github.com/siriscac/RippleView
public class RippleView extends Button {
private PointF touchPoint = new PointF();
private int radius = 150;
private Paint mPaint;
private ObjectAnimator objectAnimator;
public RippleView(Context context) {
super(context);
init();
}
public RippleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public RippleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAlpha(100);
mPaint.setColor(Color.GREEN);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchPoint.x = event.getX();
touchPoint.y = event.getY();
radius = 150;
setRadius(150);
break;
case MotionEvent.ACTION_MOVE:
touchPoint.x = event.getX();
touchPoint.y = event.getY();
setRadius(150);
break;
case MotionEvent.ACTION_UP:
objectAnimator = ObjectAnimator.ofFloat(this, "radius", 150, 1000).setDuration(400);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
setRadius(0);
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
objectAnimator.start();
break;
}
return super.onTouchEvent(event);
}
/** 根据给定的color和alpha值得到给定的color */
public int getColor(int color, float aAlpha) {
int alpha = Math.round(Color.alpha(color) * aAlpha);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
return Color.argb(alpha, red, green, blue);
}
/** 在执行ObjectAnimator的过程中就会调用此方法 */
public void setRadius(float radius) {
System.out.println("setRadius----------" + radius);
this.radius = (int) radius;
if (this.radius > 0) {
RadialGradient mRadialGradient = new RadialGradient(touchPoint.x, touchPoint.y, this.radius, getColor(
Color.GREEN, 0.1f), Color.GREEN, Shader.TileMode.MIRROR);
mPaint.setShader(mRadialGradient);
}
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(touchPoint.x, touchPoint.y, radius, mPaint);
super.onDraw(canvas);
}
}
objectAnimator = ObjectAnimator.ofFloat(this, "radius", 150, 1000).setDuration(400);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();
start之后在执行中会不断的调用setRedius(Float)方法,并不断传入最新的redius的值,这时候我们需要做的是不断修改当前redius的值并且刷新界面画新圆。
期间我们用到了RadialGradient方法。
android.graphics.RadialGradient.RadialGradient(float x, float y, float radius, int color0, int color1, TileMode tile)
Create a shader that draws a radial gradient given the center and radius.
Parameters:
x The x-coordinate of the center of the radius
y The y-coordinate of the center of the radius
radius Must be positive. The radius of the circle for this gradient
color0 The color at the center of the circle.
color1 The color at the edge of the circle.
tile The Shader tiling mode
我们可以看出各个参数的信息。大体就是这样,还有一个比较好玩的就是getColor这个方法,是根据给定的色值和alpha得出需要显示的color的值。其中几个Color的静态方法比较有意思,比如Color.red(color)
int android.graphics.Color.red(int color)
Return the red component of a color int. This is the same as saying (color >> 16) & 0xFF
Parameters:
color
它说same as (color >> 16) & 0xFF,如果去看源码的话也是这么实现的
/**
* Return the red component of a color int. This is the same as saying
* (color >> 16) & 0xFF
*/
public static int red(int color) {
return (color >> 16) & 0xFF;
}
我们假如说我们有一个色值0xFF00FF00,转成二进制就是11111111000000001111111100000000,然后右移16位就是00000000000000001111111100000000然后需要跟0xFF取与,得到00000000,也就是0x00。
跑题了,谢谢观赏。