Android 按钮按下水纹。
import android.content.Context;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ButtonTouchCircleAnimView extends ViewGroup {
private static final int HANDLER_START_UP_ANIM = 0;
private static final int HANDLER_UP_ANIM_END = 1;
private Context mContext;
private ConcurrentHashMap<Integer, CircleView> mCircleViewMap;
private int mCircleRadius;
private WeakRefHandler mHandler;
public ButtonTouchCircleAnimView(Context context) {
this(context, null);
}
public ButtonTouchCircleAnimView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mCircleViewMap = new ConcurrentHashMap<>();
mCircleRadius = (int) (mContext.getResources().getDimension(R.dimen.bottom_menu_bar_height) + DensityUtils.dip2px(mContext, 12)) / 2;
mHandler = new WeakRefHandler(mContext) {
@Override
public void handleMessage(Message msg) {
CircleView circleView = null;
switch (msg.what) {
case HANDLER_START_UP_ANIM:
int id = (int) msg.obj;
circleView = mCircleViewMap.get(id);
if (null != circleView && null != circleView.imageView) {
circleView.imageView.clearAnimation();
circleView.imageView.startAnimation(new TouchUpAnimation(id).create());
}
break;
case HANDLER_UP_ANIM_END:
id = (int) msg.obj;
circleView = mCircleViewMap.get(id);
if (null != circleView && null != circleView.imageView) {
if (!circleView.downAnimRuning) {
circleView.imageView.clearAnimation();
removeView(circleView.imageView);
mCircleViewMap.remove(id);
}
}
break;
}
}
};
}
public class CircleView {
ImageView imageView;
View mRelatedView;
boolean downAnimRuning = false;
boolean upAnimRuning = false;
boolean upAnimWaiting = false;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
public ImageView createCircleView() {
ImageView iv = new ImageView(mContext);
iv.setImageResource(R.drawable.button_touch_circle_shape);
return iv;
}
public void onButtonTouch(View v, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
CircleView circleView = mCircleViewMap.get(v.getId());
if (circleView == null) {
circleView = new CircleView();
circleView.imageView = createCircleView();
circleView.mRelatedView = v;
mCircleViewMap.put(v.getId(), circleView);
int left = v.getLeft() + v.getWidth() / 2 - mCircleRadius;
int top = v.getTop() + v.getHeight() / 2 - mCircleRadius;
int right = v.getRight() - v.getWidth() / 2 + mCircleRadius;
int bottom = v.getBottom() - v.getHeight() / 2 + mCircleRadius;
addView(circleView.imageView);
circleView.imageView.layout(left, top, right, bottom);
}
circleView.upAnimWaiting = false;
circleView.upAnimRuning = false;
circleView.downAnimRuning = true;
circleView.imageView.clearAnimation();
circleView.imageView.startAnimation(new TouchDownAnimation(v.getId()).create());
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (mCircleViewMap.get(v.getId()) != null) {
if (mCircleViewMap.get(v.getId()).downAnimRuning) {
mCircleViewMap.get(v.getId()).upAnimWaiting = true;
} else {
mCircleViewMap.get(v.getId()).imageView.clearAnimation();
mCircleViewMap.get(v.getId()).imageView.startAnimation(new TouchUpAnimation(v.getId()).create());
}
}
}
}
private class TouchDownAnimation {
private int viewId = 0;
public TouchDownAnimation(int id) {
viewId = id;
}
public AnimationSet create() {
AlphaAnimation alphaAnimation;
ScaleAnimation scaleAnimation;
alphaAnimation = new AlphaAnimation(0, 1);
scaleAnimation = new ScaleAnimation(0, 1.0f, 0, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.setDuration(180);
animationSet.setInterpolator(new DecelerateInterpolator());
animationSet.setFillAfter(true);
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mCircleViewMap.get(viewId).downAnimRuning = true;
}
@Override
public void onAnimationEnd(Animation animation) {
if (mCircleViewMap.get(viewId) != null) {
mCircleViewMap.get(viewId).downAnimRuning = false;
boolean processTheRelatedViewDisabled = !(mCircleViewMap.get(viewId).mRelatedView == null
|| mCircleViewMap.get(viewId).mRelatedView.isEnabled());
if (mCircleViewMap.get(viewId).upAnimWaiting || processTheRelatedViewDisabled) {
mCircleViewMap.get(viewId).upAnimWaiting = false;
mHandler.sendMessage(mHandler.obtainMessage(HANDLER_START_UP_ANIM, viewId));
}
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
return animationSet;
}
}
private class TouchUpAnimation {
private int viewId = 0;
public TouchUpAnimation(int id) {
viewId = id;
}
public AnimationSet create() {
AlphaAnimation alphaAnimation;
ScaleAnimation scaleAnimation;
alphaAnimation = new AlphaAnimation(1, 0);
scaleAnimation = new ScaleAnimation(1.f, 2.f, 1.f, 2.f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.setDuration(400);
animationSet.setInterpolator(new DecelerateInterpolator());
animationSet.setFillAfter(true);
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mCircleViewMap.get(viewId).upAnimRuning = true;
}
@Override
public void onAnimationEnd(Animation animation) {
if (mCircleViewMap.get(viewId) != null) {
mCircleViewMap.get(viewId).upAnimRuning = false;
mHandler.sendMessage(mHandler.obtainMessage(HANDLER_UP_ANIM_END, viewId));
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
return animationSet;
}
}
public void abortAnimation(int viewId) {
if (mCircleViewMap.get(viewId) != null) {
if (null != mHandler) {
mHandler.removeMessages(HANDLER_START_UP_ANIM, viewId);
mHandler.removeMessages(HANDLER_UP_ANIM_END, viewId);
}
mCircleViewMap.get(viewId).imageView.clearAnimation();
removeView(mCircleViewMap.get(viewId).imageView);
mCircleViewMap.remove(viewId);
}
}
public void abortAllAnimation() {
Iterator iter = mCircleViewMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Integer key = (Integer) entry.getKey();
abortAnimation(key);
}
}
}