Android实现简单点赞动画

本文实例为大家分享了Android实现简单点赞动画的具体代码,供大家参考,具体内容如下
思路
【Android实现简单点赞动画】1、找到Activity中DecorView的RootView
2、确定点赞控件位于屏幕中的坐标值
3、将点赞效果View加入到RootView中, 给效果View添加自己想要的动画效果.
4、重复点击时候, 需要将效果View先移除掉再重新加入到RootView中.

代码

/** * 普通点赞效果, 点击控件后出现一个View上浮 */public class ViewLikeUtils {public interface ViewLikeClickListener {/*** @param view被点赞的按钮* @param toggle开关* @param viewLikeUtils 工具类本身*/void onClick(View view, boolean toggle, ViewLikeUtils viewLikeUtils); }// 被点击的按钮private View mClickView; private View mAnimView; private ViewLikeClickListener mListener; private boolean toggle = false; // 点击开关标识private int mX; // 距离屏幕左侧距离private int mY; // 距离屏幕顶端距离, 越往下数值越大/*** @param mClickView 被点击的View* @param mAnimView点赞后, 向上浮动的View* @param mListener被点击的View,点击后的回调事件.*/public ViewLikeUtils(View mClickView, View mAnimView, @NonNull ViewLikeClickListener mListener) {this.mClickView = mClickView; this.mAnimView = mAnimView; this.mListener = mListener; initListener(); }/*** 设置View的监听*/private void initListener() {mClickView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {getLocation(); // 获取被点击View的坐标toggle = !toggle; if (mListener != null) {mListener.onClick(mClickView, toggle, ViewLikeUtils.this); }// mView.performClick(); }// 正常的OnClickListener将无法调用return true; }}); }/*** 获取View在屏幕中的坐标*/private void getLocation() {int[] mLocation = new int[2]; mClickView.getLocationOnScreen(mLocation); mX = mLocation[0]; mY = mLocation[1]; }/*** 开始动画*/private void startAnim(ValueAnimator valueAnimator) {valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {mAnimView.setAlpha(1 - (Float) valueAnimator.getAnimatedFraction()); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mAnimView.getLayoutParams(); params.topMargin = (int) (mY - mAnimView.getMeasuredHeight() - 100 * valueAnimator.getAnimatedFraction()); mAnimView.setLayoutParams(params); }}); valueAnimator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {removeChildView(mAnimView); }@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}}); valueAnimator.start(); }/*** 将上浮控件添加到屏幕中** @param animview*/private void addAnimView(View animview) {Activity activityFromView = getActivityFromView(mClickView); if (activityFromView != null) {FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); FrameLayout mRootView = (FrameLayout) activityFromView.getWindow().getDecorView().getRootView(); mRootView.addView(animview, params); // 测量浮动View的大小animview.measure(0, 0); params.topMargin = (int) (mY - animview.getMeasuredHeight()); params.leftMargin = mX + mClickView.getMeasuredWidth() / 2 - animview.getMeasuredHeight() / 2; animview.setLayoutParams(params); }}/*** 开始动画*/public void startLikeAnim(ValueAnimator valueAnimator) {removeChildView(mAnimView); addAnimView(mAnimView); startAnim(valueAnimator); }/*** 获取Activity** @param view* @return*/public Activity getActivityFromView(View view) {if (null != view) {Context context = view.getContext(); while (context instanceof ContextWrapper) {if (context instanceof Activity) {return (Activity) context; }context = ((ContextWrapper) context).getBaseContext(); }}return null; }/*** 将子View从父容器中去除*/private void removeChildView(View mChildView) {ViewGroup parentViewGroup = (ViewGroup) mChildView.getParent(); if (parentViewGroup != null) {parentViewGroup.removeView(mChildView); }}}

使用
// 效果Viewval textView = TextView(this@MainActivity2)textView.text = "+1"textView.setTextColor(Color.RED)textView.textSize = mBtn.textSize// 效果View动画val animator = ValueAnimator.ofInt(10, 200)animator.duration = 800ViewLikeUtils(findViewById

效果
Android实现简单点赞动画
文章图片

贝塞尔动画点赞效果
思路其实差不多, 具体看代码
public class ViewLikeBesselUtils {public interface ViewLikeClickListener {/*** @param view被点赞的按钮* @param toggle开关* @param viewLikeBesselUtils 工具类本身*/void onClick(View view, boolean toggle, ViewLikeBesselUtils viewLikeBesselUtils); }// 被点击的按钮private View mClickView; private View[] mAnimViews; private ViewLikeClickListener mListener; private boolean toggle = false; // 点击开关标识private int mX; // 距离屏幕左侧距离private int mY; // 距离屏幕顶端距离, 越往下数值越大private Random mRandom = new Random(); // 随机数/*** @param mClickView 被点击的View* @param mAnimViews 点赞后, 向上浮动的View数组* @param mListener被点击的View,点击后的回调事件.*/public ViewLikeBesselUtils(View mClickView, View[] mAnimViews, @NonNull ViewLikeClickListener mListener) {this.mClickView = mClickView; this.mAnimViews = mAnimViews; this.mListener = mListener; initListener(); }/*** 设置View的监听*/private void initListener() {mClickView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {getLocation(); // 获取被点击View的坐标toggle = !toggle; if (mListener != null) {mListener.onClick(mClickView, toggle, ViewLikeBesselUtils.this); }// mView.performClick(); }// 正常的OnClickListener将无法调用return true; }}); }/*** 获取View在屏幕中的坐标*/private void getLocation() {int[] mLocation = new int[2]; mClickView.getLocationInWindow(mLocation); mX = mLocation[0]; mY = mLocation[1]; }/*** 开始动画** @param mAnimView*/private void startAnim(View mAnimView, int mTime) {AnimatorSet animatorSet = new AnimatorSet(); ArrayList interpolators = new ArrayList<>(); interpolators.add(new AccelerateInterpolator()); interpolators.add(new DecelerateInterpolator()); interpolators.add(new AccelerateDecelerateInterpolator()); interpolators.add(new LinearInterpolator()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {animatorSet.setInterpolator(interpolators.get(mRandom.nextInt(4))); }// 合并动画animatorSet.playTogether(getAnimationSet(mAnimView), getBezierAnimatorSet(mAnimView)); animatorSet.setTarget(mAnimView); animatorSet.setDuration(mTime); animatorSet.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {removeChildView(mAnimView); }@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}}); animatorSet.start(); }/*** 将上浮控件添加到屏幕中** @param animview*/private void addAnimView(View animview) {Activity activityFromView = getActivityFromView(mClickView); if (activityFromView != null) {FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); FrameLayout mRootView = (FrameLayout) activityFromView.getWindow().getDecorView().getRootView(); mRootView.addView(animview, params); }}/*** 开始动画*/public void startLikeAnim() {for (View mAnimView : mAnimViews) {removeChildView(mAnimView); addAnimView(mAnimView); startAnim(mAnimView, mRandom.nextInt(1500)); }}/*** 获取属性动画*/private AnimatorSet getAnimationSet(View mView) {ObjectAnimator scaleX = ObjectAnimator.ofFloat(mView, "scaleX", 0.4f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(mView, "scaleY", 0.4f, 1f); ObjectAnimator alpha = ObjectAnimator.ofFloat(mView, "alpha", 1f, 0.2f); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleX, scaleY, alpha); return animatorSet; }/*** 获取贝塞尔动画*/private ValueAnimator getBezierAnimatorSet(View mView) {// 测量viewmView.measure(0, 0); // 屏幕宽int width = getActivityFromView(mClickView).getWindowManager().getDefaultDisplay().getWidth(); int mPointF0X = mX + mRandom.nextInt(mView.getMeasuredWidth()); int mPointF0Y = mY - mView.getMeasuredHeight()/2; // 起点PointF pointF0 = new PointF(mPointF0X, mPointF0Y); // 终点PointF pointF3 = new PointF(mRandom.nextInt(width - 100), 0f); // 第二点PointF pointF1 = new PointF(mRandom.nextInt(width - 100), (float) (mY * 0.7)); // 第三点PointF pointF2 = new PointF(mRandom.nextInt(width - 100), (float) (mY * 0.3)); BezierEvaluator be = new BezierEvaluator(pointF1, pointF2); ValueAnimator bezierAnimator = ValueAnimator.ofObject(be, pointF0, pointF3); bezierAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {PointF pointF = (PointF) valueAnimator.getAnimatedValue(); mView.setX(pointF.x); mView.setY(pointF.y); }}); return bezierAnimator; }/*** 获取Activity** @param view* @return*/public Activity getActivityFromView(View view) {if (null != view) {Context context = view.getContext(); while (context instanceof ContextWrapper) {if (context instanceof Activity) {return (Activity) context; }context = ((ContextWrapper) context).getBaseContext(); }}return null; }/*** 将子View从父容器中去除*/private void removeChildView(View mChildView) {ViewGroup parentViewGroup = (ViewGroup) mChildView.getParent(); if (parentViewGroup != null) {parentViewGroup.removeView(mChildView); }}}public class BezierEvaluator implements TypeEvaluator {/*** 这2个点是控制点*/private PointF point1; private PointF point2; public BezierEvaluator(PointF point1, PointF point2) {this.point1 = point1; this.point2 = point2; }/*** @param t* @param point0 初始点* @param point3 终点* @return*/@Overridepublic PointF evaluate(float t, PointF point0, PointF point3) {PointF point = new PointF(); point.x = point0.x * (1 - t) * (1 - t) * (1 - t)+ 3 * point1.x * t * (1 - t) * (1 - t)+ 3 * point2.x * t * t * (1 - t) * (1 - t)+ point3.x * t * t * t; point.y = point0.y * (1 - t) * (1 - t) * (1 - t)+ 3 * point1.y * t * (1 - t) * (1 - t)+ 3 * point2.y * t * t * (1 - t) * (1 - t)+ point3.y * t * t * t; return point; }}

使用
mBtn = findViewById(R.id.btn_anim)val mTVS = arrayOfNulls(200)for (i in 0..199) {val mTV = TextView(this@MainActivity2)mTV.text = "赞"mTV.setTextColor(Color.RED)mTV.textSize = mBtn.textSizemTVS[i] = mTV}ViewLikeBesselUtils(mBtn, mTVS) { view, toggle, viewLikeBesselUtils ->viewLikeBesselUtils.startLikeAnim()}

效果
Android实现简单点赞动画
文章图片

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读