android 点击特效动画


/**
 * 控件的点击动画
 */
public class AnimClickUtil {
    //动画执行速度
    public  final int ANIM_SPEED = 300;

    //旋转角度
    private  final float POTATION_VALUE = 7f;

    //变速器
    public OvershootInterpolator interpolator = new OvershootInterpolator(3f);

    //缩放比例
    private  final float SCALE_END = 0.8f;

    //阴影最小值
    private  final float SHADOW_END = 0;

    private boolean isClick;    //标识点击是否有效,有效执行回掉,否则只执行动画

    /**
     * 启动按压动画
     *
     * @param view   执行动画的View
     * @param superb 效果类型【true:华丽效果】【false:缩放效果】
     * @param x      触点X坐标
     * @param y      触点Y坐标
     * @return 动画执行顶点
     */

    public int startAnimDown(View view, boolean superb, float x, float y) {
        if (false == view.isClickable()) {
            return 1;
        }
        int pivot;
        // 缩放效果
        if (false == superb) {
            pivot = 0;
            // 执行缩小动画【缩放效果】
            froBig_ToSmall(view);
            return pivot;
        }
        // 华丽效果
        int w = view.getWidth();
        int h = view.getHeight();
        if ((w / 5 * 2) < x && x < (w / 5 * 3) && (h / 5 * 2) < y && y < (h / 5 * 3)) {
            pivot = 0;
        } else if (x < w / 2 && y < h / 2) { // 第一象限
            if (x / (w / 2) > y / (h / 2)) {
                pivot = 1;
            } else {
                pivot = 4;
            }
        } else if (x < w / 2 && y >= h / 2) { // 第四象限
            if ((w - x) / (w / 2) > y / (h / 2)) {
                pivot = 4;
            } else {
                pivot = 3;
            }
        } else if (x >= w / 2 && y >= h / 2) { // 第三象限
            if ((w - x) / (w / 2) > (h - y) / (h / 2)) {
                pivot = 3;
            } else {
                pivot = 2;
            }
        } else { // 第二象限
            if (x / (w / 2) > (h - y) / (h / 2)) {
                pivot = 2;
            } else {
                pivot = 1;
            }
        }
        String anim = "";
        switch (pivot) {
            case 0:
                view.setPivotX(w / 2);
                view.setPivotY(h / 2);
                // 执行缩小动画【缩放效果】
                froBig_ToSmall(view);
                return pivot;
            case 1:
            case 3:
                anim = "rotationX";
                break;
            case 2:
            case 4:
                anim = "rotationY";
                break;
            default:
                break;
        }
        view.setPivotX(w / 2);
        view.setPivotY(h / 2);
        // 执行缩小动画【华丽效果】
        froBig_ToSmall(view, pivot, anim);
        return pivot;
    }

    /**
     * 启动抬起动画
     *
     * @param view  执行动画的View
     * @param pivot 动画执行顶点
     */
    public void startAnimUp(View view, int pivot,boolean isClick) {
        this.isClick = isClick;
        if (false == view.isClickable()) {
            return;
        }
        if (pivot == 0) {
            // 执行放大动画【缩放效果】
            froSmall_ToBig(view);
        } else {
            String anim = "";
            switch (pivot) {
                case 1:
                case 3:
                    anim = "rotationX";
                    break;
                case 2:
                case 4:
                    anim = "rotationY";
                    break;
            }
            // 执行放大动画【华丽效果】
            froSmall_ToBig(view, pivot, anim);
        }
    }

    /**
     * 【华丽效果】从大过渡到小
     */
    private void froBig_ToSmall(View view, int pivot, String anim) {
        float potationEnd;
        if (pivot == 3 || pivot == 4) {
            potationEnd = 0 - POTATION_VALUE;
        } else {
            potationEnd = POTATION_VALUE;
        }
        int potationStart = 0;
        if (pivot == 2 || pivot == 4) {
            potationStart = (int) view.getRotationY();
        } else {
            potationStart = (int) view.getRotationX();
        }
        ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potationStart, potationEnd)
                .setDuration(ANIM_SPEED);
        animObject.setInterpolator(interpolator);
        animObject.start();
    }

    /**
     * 【华丽效果】从小过渡到大
     */
    private void froSmall_ToBig(View view, int pivot, String anim) {
        int potation;
        if (pivot == 2 || pivot == 4) {
            potation = (int) view.getRotationY();
        } else {
            potation = (int) view.getRotationX();
        }
        ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potation, 0).setDuration(ANIM_SPEED);
        animObject.setInterpolator(interpolator);
        animObject.start();
    }

    /**
     * 【缩放效果】从大过渡到小
     */
    public void froBig_ToSmall(View view) {
        try {
            float tzStart = 0;
            Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);
            if (android.os.Build.VERSION.SDK_INT >= 21) {
                tzStart = view.getTranslationZ();
                if (viewTag == null || false == viewTag instanceof Float) {
                    view.setTag(R.string.anim_click_tag_key_translation_z, tzStart);
                }
            }

            //控件的长宽高执行缩小动画
            PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, SHADOW_END);
            PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), SCALE_END);
            PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), SCALE_END);

            ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);
            animatorD.setInterpolator(interpolator);
            animatorD.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    //动画结束时的回掉
                    if (listener1 != null && isClick) {
                        listener1.onDownEnd();
                    }
                }
            });
            animatorD.start();
        } catch (Exception e) {

        }
    }

    /**
     * 【缩放效果】从小过渡到大
     */
    public void froSmall_ToBig(View view) {
        try {
            float tzStart = 0, tzEnd = 0;
            Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);
            if (android.os.Build.VERSION.SDK_INT >= 21) {
                tzStart = view.getTranslationZ();
                if (viewTag != null && viewTag instanceof Float) {
                    tzEnd = (Float) viewTag;
                }
            }

            //控件的长宽高执行缩小后的恢复动画
            PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, tzEnd);
            PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), 1);
            PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), 1);

            ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);
            animatorD.setInterpolator(interpolator);
            animatorD.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    //动画结束时的回掉
                    if (listener1 != null && isClick) {
                        listener1.onUpEnd();
                    }
                }
            });
            animatorD.start();
        } catch (Exception e) {

        }
    }

    public interface OnAnimEndListener {
        void onDownEnd();
        void onUpEnd();
    }

    public OnAnimEndListener listener1;
    public void setAnimEndListener(OnAnimEndListener listener) {
        listener1 = listener;
    }
}
/***
 * 只要控件外层套上该控件,即可实现点击动画
 */
public class AnimRelativeLayout extends RelativeLayout {

    /**
     * 动画模式【true:华丽效果——缩放加方向】【false:只缩放】
     * 华丽效果:即点击控件的 上、下、左、右、中间时的效果都不一样
     * 普通效果:即点击控件的任意部位,都只是缩放效果,与 华丽效果模式下 点击控件中间时的动画一样
     **/
    private boolean superb = false;

    /**
     * 顶点判断【0:中间】【1:上】【2:右】【3:下】【4:左】
     **/
    private int pivot = 0;
    private AnimClickUtil bamAnim;

    public AnimRelativeLayout(Context context) {
        this(context,null);
        this.setClickable(true);
    }

    public AnimRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        this.setClickable(true);
    }

    public AnimRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.setClickable(true);
        initView();
    }

    private void initView() {
        bamAnim = new AnimClickUtil();
    }

    /**
     * 打开/关闭华丽效果,默认时关闭的
     */
    public void openSuperb(boolean isOpen) {
        superb = isOpen;
    }

    @Override
    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                pivot = bamAnim.startAnimDown(this, superb, event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_CANCEL:
                bamAnim.startAnimUp(this, pivot,false);
                break;
            case MotionEvent.ACTION_UP:
                bamAnim.startAnimUp(this, pivot,true);
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);

    }

    public void setDownEndListener(AnimClickUtil.OnAnimEndListener listener) {
        bamAnim.setAnimEndListener(listener);
    }

使用方式:直接在外层嵌套Layout即可。

效果如下:

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值