ThumbsUpView.java 7.81 KB
/*
 * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
 */

package com.wd.common.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;


import com.wd.base.log.Logger;
import com.wd.common.listener.MyClickListener;
import com.wd.fastcoding.base.R;

import java.security.SecureRandom;

/**
 * 描述:点赞动画view
 *
 * @author : lvjinhui
 * @since: 2022/7/7
 */
public class ThumbsUpView extends RelativeLayout {
    /**
     * 点击的时间间隔
     */
    private static long INTERVAL = 300;

    /**
     * 记录上一次的点击时间
     */
    private long lastClickTime = 0;

    private final long value0_5 = 50L;

    private final long value1 = 100L;

    private final long value1_5 = 150L;

    private final int value1_5_int = 150;

    private final int value2 = 200;

    private final int value3 = 150;

    private final long value3L = 300L;

    private final long value4 = 400L;

    private final Float value6 = -600F;

    private final long value7 = 700L;

    private final long value8 = 800L;

    private Context mContext;

    /**
     * 随机心形图片角度
     */
    private float[] num = {-30, -20, 0, 20, 30};

    private long[] mHits = new long[2];

    private MyClickListener.MyClickCallBack clickCallBack;

    private MyClickListener myClickListener;

    private int drawableId = R.mipmap.icon_bottom_liked;

    public ThumbsUpView(Context context) {
        this(context, null);
    }

    public ThumbsUpView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ThumbsUpView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
    }

    public void setAnimalDrawableId(int drawableId) {
        this.drawableId = drawableId;
    }

    /**
     * 监听点击事件
     *
     * @param event
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 获取点击时间
                long currTime = SystemClock.uptimeMillis();
                // 判断点击之间的时间差
                long interval = currTime - lastClickTime;
                lastClickTime = currTime;
                // 小于0.2秒,拦截事件,并做处理
                if (interval < INTERVAL) {
                    setAnnouncement(event.getX(),event.getY());
                }
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (myClickListener!=null){
            myClickListener.onTouch(this,event);
        }
        return super.onTouchEvent(event);
    }

    private ObjectAnimator scaleAni(View view, String propertyName, Float from, Float to, Long time, Long delay) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, propertyName, from, to);
        objectAnimator.setInterpolator(new LinearInterpolator());
        objectAnimator.setStartDelay(delay);
        objectAnimator.setDuration(time);
        return objectAnimator;
    }

    private ObjectAnimator translationX(View view, Float from, Float to, Long time, Long delayTime) {
        ObjectAnimator ani = ObjectAnimator.ofFloat(view, "translationX", from, to);
        ani.setInterpolator(new LinearInterpolator());
        ani.setStartDelay(delayTime);
        ani.setDuration(time);
        return ani;
    }

    private ObjectAnimator translationY(View view, Float from, Float to, Long time, Long delayTime) {
        ObjectAnimator ani = ObjectAnimator.ofFloat(view, "translationY", from, to);
        ani.setInterpolator(new LinearInterpolator());
        ani.setStartDelay(delayTime);
        ani.setDuration(time);
        return ani;
    }

    private ObjectAnimator alphaAni(View view, Float from, Float to, Long time, Long delayTime) {
        ObjectAnimator ani = ObjectAnimator.ofFloat(view, "alpha", from, to);
        ani.setInterpolator(new LinearInterpolator());
        ani.setStartDelay(delayTime);
        ani.setDuration(time);
        return ani;
    }

    private ObjectAnimator rotation(View view, Long time, Long delayTime, Float values) {
        ObjectAnimator ani = ObjectAnimator.ofFloat(view, "rotation", values);
        ani.setInterpolator(new TimeInterpolator() {
            @Override
            public float getInterpolation(float input) {
                return 0;
            }
        });
        ani.setStartDelay(delayTime);
        ani.setDuration(time);
        return ani;
    }

    public void setOnClickListener(MyClickListener.MyClickCallBack onClickListener) {
        this.clickCallBack = onClickListener;
        myClickListener = new MyClickListener(clickCallBack);
    }

    public MyClickListener.MyClickCallBack getOnClickListener() {
        return clickCallBack;
    }

    public void setAnnouncement(float x,float y){
        Logger.t("ThumbsUpView").i("点击动画 ===> x y"+x +"/"+y);
        if(drawableId == -1){
            return;
        }
        final ImageView imageView = new ImageView(mContext);
        // 设置展示的位置,需要在手指触摸的位置上方,即触摸点是心形的右下角的位置
        LayoutParams params = new LayoutParams(value2, value2);
        params.leftMargin = (int) x - value1_5_int;
        params.topMargin = (int) y - value3;
        // 设置图片资源
        imageView.setImageDrawable(getResources().getDrawable(drawableId));
        imageView.setLayoutParams(params);
        // 把IV添加到父布局当中
        addView(imageView);
        // 设置控件的动画
        AnimatorSet animatorSet = new AnimatorSet();
        // 缩放动画,X轴2倍缩小至0 .9倍
        animatorSet.play(scaleAni(imageView, "scaleX", 2f, 0.9f, value1, 0L))
                // 缩放动画,Y轴2倍缩放至0.9倍
                .with(scaleAni(imageView, "scaleY", 2f, 0.9f, value1, 0L))
                // 旋转动画,随机旋转角
                .with(rotation(imageView, 0L, 0L, num[new SecureRandom().nextInt(4)]))
                // 渐变透明动画,透明度从0-1
                .with(alphaAni(imageView, 0F, 1F, value1, 0L))
                // 缩放动画,X轴0.9倍缩小至
                .with(scaleAni(imageView, "scaleX", 0.9f, 1F, value0_5, value1_5))
                // 缩放动画,Y轴0.9倍缩放至
                .with(scaleAni(imageView, "scaleY", 0.9f, 1F, value0_5, value1_5))
                // 位移动画,Y轴从0上移至600
                .with(translationY(imageView, 0f, value6, value8, value4))
                // 透明动画,从1-0
                .with(alphaAni(imageView, 1F, 0F, value3L, value4))
                // 缩放动画,X轴1至3倍
                .with(scaleAni(imageView, "scaleX", 1F, 3F, value7, value4))
                // 缩放动画,Y轴1至3倍
                .with(scaleAni(imageView, "scaleY", 1F, 3F, value7, value4));
        // 开始动画
        animatorSet.start();
        // 设置动画结束监听
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                // 当动画结束以后,需要把控件从父布局移除
                removeViewInLayout(imageView);
            }
        });
    }


}