diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierAnimationView.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierAnimationView.java new file mode 100644 index 0000000000..85ad93badb --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierAnimationView.java @@ -0,0 +1,141 @@ +package com.mogo.module.common.animation; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.PointF; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.LinearInterpolator; +import android.widget.ImageView; +import android.widget.RelativeLayout; + +import androidx.core.content.ContextCompat; + +import com.mogo.module.common.R; + +import java.util.Random; + +public class BezierAnimationView extends RelativeLayout implements View.OnClickListener { + private String TAG = "BezierAnimationView"; + private Context context; + private int[] animation_drawable = { + R.drawable.icon_common_heart_animation_vr00, + R.drawable.icon_heart_unchoose_other, + R.drawable.icon_map_marker_living}; + private Random random = new Random(); + private int width = 500, height = 210; + private int drawableWidth, drawableHeight; + + public BezierAnimationView(Context context) { + this(context, null); + } + + public BezierAnimationView(Context context, AttributeSet attributes) { + this(context, attributes, 0); + } + + public BezierAnimationView(Context context, AttributeSet attributes, int defStyleAttr) { + super(context, attributes, defStyleAttr); + this.context = context; + //3、设置点击事件 + setOnClickListener(this); + //4、获取点赞图片的宽高 + Drawable drawable = ContextCompat.getDrawable(context, R.drawable.icon_common_heart_animation_vr02); + drawableWidth = drawable.getIntrinsicWidth(); + drawableHeight = drawable.getIntrinsicHeight(); + } + + @Override + public void onClick(View view) { + Log.d("执行点赞动画", "ppp"); + bezierAnimation(); + } + + private void bezierAnimation() { + final ImageView imageView = new ImageView(context); + imageView.setBackgroundResource(animation_drawable[random.nextInt(animation_drawable.length - 1)]); + RelativeLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.addRule(ALIGN_BOTTOM); + params.addRule(CENTER_HORIZONTAL); + imageView.setLayoutParams(params); + addView(imageView); + + /* + * 开始执行点赞效果 + * */ + AnimatorSet animatorSet = getAnimatorSet(imageView); + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + //3、动画执行后移除View + removeView(imageView); + } + }); + animatorSet.start(); + } + + private AnimatorSet getAnimatorSet(ImageView imageView) { + AnimatorSet enter = new AnimatorSet(); + /* + * 缩放动画 + * */ + AnimatorSet scaleAnimator = new AnimatorSet(); + ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 0.8f, 1f); + ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0.8f, 1f); + ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 0.8f, 1f); + scaleAnimator.setDuration(500); + scaleAnimator.playTogether(alpha, scaleX, scaleY); + + /* + * 贝塞尔动画 + * */ + ValueAnimator bezierAnimator = getBezierValueAnimator(imageView); + /* + * 两个动画按顺序播放 + * */ + enter.playSequentially(scaleAnimator, bezierAnimator); + return enter; + } + + /** + * 获取贝塞尔曲线动画 + * + * @param target + * @return + */ + private ValueAnimator getBezierValueAnimator(View target) { + + //初始化一个BezierEvaluator + BezierEvaluator evaluator = new BezierEvaluator(getPointF(1), getPointF(1)); + + // 起点固定,终点随机 + ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF((width - 40) / 2, height - 80), + new PointF(random.nextInt(getWidth()), 0)); + animator.addUpdateListener(new BezierListener(target)); + animator.setTarget(target); + animator.setDuration(3000); + return animator; + } + + /** + * 获取一条路径的两个控制点 + * + * @param scale + */ + private PointF getPointF(int scale) { + + PointF pointF = new PointF(); + //减去100 是为了控制 x轴活动范围 + pointF.x = random.nextInt((width)); + //再Y轴上 为了确保第二个控制点 在第一个点之上,我把Y分成了上下两半 + pointF.y = random.nextInt((height)) / scale; + return pointF; + } +} diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierEvaluator.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierEvaluator.java new file mode 100644 index 0000000000..6effc925b1 --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierEvaluator.java @@ -0,0 +1,45 @@ +package com.mogo.module.common.animation; + +import android.animation.TypeEvaluator; +import android.graphics.PointF; + +/** + * 贝塞尔曲线估值器:计算动画的执行轨迹 + * + * @params 传入贝塞尔曲线需要的四个点 + * @return 通过计算返回贝塞尔曲线的坐标 + */ +public class BezierEvaluator implements TypeEvaluator { + + private PointF pointF1; + private PointF pointF2; + + public BezierEvaluator(PointF point1, PointF point2) { + this.pointF1 = point1; + this.pointF2 = point2; + } + + @Override + public PointF evaluate(float time, PointF startValue, PointF endValue) { + float timeLeft = 1.0f - time; + + //结果 + PointF point = new PointF(); + + PointF point0 = (PointF)startValue;//起点 + PointF point3 = (PointF)endValue;//终点 + + // 贝塞尔公式 + point.x = timeLeft * timeLeft * timeLeft * (point0.x) + + 3 * timeLeft * timeLeft * time * (pointF1.x) + + 3 * timeLeft * time * time * (pointF2.x) + + time * time * time * (point3.x); + + point.y = timeLeft * timeLeft * timeLeft * (point0.y) + + 3 * timeLeft * timeLeft * time * (pointF1.y) + + 3 * timeLeft * time * time * (pointF2.y) + + time * time * time * (point3.y); + + return point; + } +} \ No newline at end of file diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierListener.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierListener.java new file mode 100644 index 0000000000..04ab1129c2 --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierListener.java @@ -0,0 +1,24 @@ +package com.mogo.module.common.animation; + +import android.animation.ValueAnimator; +import android.graphics.PointF; +import android.view.View; + +public class BezierListener implements ValueAnimator.AnimatorUpdateListener { + + private View target; + + public BezierListener(View target) { + this.target = target; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + //这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦 + PointF pointF = (PointF) animation.getAnimatedValue(); + target.setX(pointF.x); + target.setY(pointF.y); + // 这里偷个懒,顺便做一个alpha动画,这样alpha渐变也完成啦 + target.setAlpha(1 - animation.getAnimatedFraction()); + } +} \ No newline at end of file diff --git a/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr00.png b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr00.png new file mode 100644 index 0000000000..5246d61ccc Binary files /dev/null and b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr00.png differ diff --git a/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr01.png b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr01.png new file mode 100644 index 0000000000..5246d61ccc Binary files /dev/null and b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr01.png differ diff --git a/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr02.png b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr02.png new file mode 100644 index 0000000000..5246d61ccc Binary files /dev/null and b/modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr02.png differ