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即可。

效果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章