From b4cd08c766b828dad8718bed3360915bec2f0de9 Mon Sep 17 00:00:00 2001 From: liujing Date: Thu, 17 Dec 2020 16:46:23 +0800 Subject: [PATCH] =?UTF-8?q?[add]=20=E8=B4=9D=E5=A1=9E=E5=B0=94=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/animation/BezierAnimationView.java | 141 ++++++++++++++++++ .../common/animation/BezierEvaluator.java | 45 ++++++ .../common/animation/BezierListener.java | 24 +++ .../icon_common_heart_animation_vr00.png | Bin 0 -> 4386 bytes .../icon_common_heart_animation_vr01.png | Bin 0 -> 4386 bytes .../icon_common_heart_animation_vr02.png | Bin 0 -> 4386 bytes 6 files changed, 210 insertions(+) create mode 100644 modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierAnimationView.java create mode 100644 modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierEvaluator.java create mode 100644 modules/mogo-module-common/src/main/java/com/mogo/module/common/animation/BezierListener.java create mode 100644 modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr00.png create mode 100644 modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr01.png create mode 100644 modules/mogo-module-common/src/main/res/drawable-xhdpi/icon_common_heart_animation_vr02.png 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 0000000000000000000000000000000000000000..5246d61ccc4779122340b8b2557aad23029f86c6 GIT binary patch literal 4386 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