Android 按钮按下释放水纹实现

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);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值