安卓直播送禮物的愛心動畫
阿新 • • 發佈:2019-02-05
貝塞爾曲線
//動畫愛心類import android.animation.TypeEvaluator; import android.graphics.PointF; /** * Created by peng on 2017/11/13. */ public class BezierEvaluator2 implements TypeEvaluator<PointF> { private PointF pointF1; private PointF pointF2; public BezierEvaluator2(PointF pointF1, PointF pointF2) { this.pointF1 = pointF1; this.pointF2 = pointF2; } @Override public PointF evaluate(float time, PointF startValue, PointF endValue) { //建立一個PointF物件 PointF point = new PointF(); float timeLeft = 1 - time; point.x = timeLeft * timeLeft * timeLeft * (startValue.x) + 3 * timeLeft * timeLeft * time * (pointF1.x) + 3 * timeLeft * time * time * (pointF2.x) + time * time * time * (endValue.x); point.y = timeLeft * timeLeft * timeLeft * (startValue.y) + 3 * timeLeft * timeLeft * time * (pointF1.y) + 3 * timeLeft * time * time * (pointF2.y) + time * time * time * (endValue.y); return point; } }
在佈局中應用: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.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.widget.ImageView; import android.widget.RelativeLayout; import com.sxs.huoshanvideo.R; import java.util.Random; /** * Created by peng on 2017/11/12. compile 'me.yifeiyuan.periscopelayout:library:1.0.0' */ public class FavorLayout extends RelativeLayout { private int mHeight;//FavorLayout的高度 private int mWidth;//FavorLayout的寬度 private Drawable[] drawables; private int dHeight; private int dWidth; private Interpolator line = new LinearInterpolator(); private Interpolator acc = new AccelerateInterpolator(); private Interpolator dce = new DecelerateInterpolator(); private Interpolator accdec = new AccelerateDecelerateInterpolator(); private Interpolator interpolators[]; private LayoutParams lp; private Random random = new Random(); public FavorLayout(Context context) { this(context, null); } public FavorLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { drawables = new Drawable[3]; Drawable red = getResources().getDrawable(R.drawable.pl_red); Drawable yellow = getResources().getDrawable(R.drawable.pl_yellow); Drawable blue = getResources().getDrawable(R.drawable.pl_blue); drawables[0] = red; drawables[1] = yellow; drawables[2] = blue; dHeight = red.getIntrinsicHeight(); dWidth = red.getIntrinsicWidth(); lp = new LayoutParams(dWidth, dHeight); lp.addRule(CENTER_HORIZONTAL, TRUE); lp.addRule(ALIGN_PARENT_BOTTOM, TRUE); //初始化插補器 interpolators = new Interpolator[4]; interpolators[0] = line; interpolators[1] = acc; interpolators[2] = dce; interpolators[3] = accdec; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = getMeasuredHeight(); mHeight = getMeasuredWidth(); } public void addHeart() { ImageView imageView = new ImageView(getContext()); imageView.setImageDrawable(drawables[new Random().nextInt(3)]); imageView.setLayoutParams(lp); addView(imageView); Animator set = getAnimator(imageView); set.addListener(new AnimEndListener(imageView)); set.start(); } private Animator getAnimator(View target) { AnimatorSet set = getEnterAnimtor(target); ValueAnimator bezierValueAnimator = getBezierValueAnimator(target); AnimatorSet finalSet = new AnimatorSet(); finalSet.playSequentially(set); finalSet.playSequentially(set, bezierValueAnimator); finalSet.setInterpolator(interpolators[random.nextInt(4)]); finalSet.setTarget(target); return finalSet; } /** * 讓心形走貝塞爾曲線的動畫 * @param target * @return */ private ValueAnimator getBezierValueAnimator(View target) { //貝塞爾曲線 BezierEvaluator2 bezierEvaluator = new BezierEvaluator2(getPointF(2), getPointF(1)); ValueAnimator valueAnimator = ValueAnimator.ofObject(bezierEvaluator, new PointF((mWidth - dWidth) / 2, mHeight - dHeight), new PointF (random.nextInt(getWidth()), 0)); valueAnimator.addUpdateListener(new BezierListenr(target)); valueAnimator.setTarget(target); valueAnimator.setDuration(3000); return valueAnimator; } /** * 給佈局新增心形的動畫 * @param target * @return */ private AnimatorSet getEnterAnimtor(final View target) { ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f, 1f); ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 0.2f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 0.2f, 1f); AnimatorSet enter = new AnimatorSet(); enter.setDuration(500); enter.setInterpolator(new LinearInterpolator()); enter.playTogether(alpha, scaleX, scaleY); enter.setTarget(target); return enter; } private PointF getPointF(int scale) { PointF pointF = new PointF(); pointF.x = random.nextInt((mWidth));//減去100 是為了控制 x軸活動範圍,看效果 隨意~~ //再Y軸上 為了確保第二個點 在第一個點之上,我把Y分成了上下兩半 這樣動畫效果好一些 也可以用其他方法 pointF.y = random.nextInt((mHeight)); return pointF; } private class BezierListenr implements ValueAnimator.AnimatorUpdateListener { private View target; public BezierListenr(View target) { this.target = target; } @Override public void onAnimationUpdate(ValueAnimator animation) { PointF pointF = (PointF) animation.getAnimatedValue(); target.setX(pointF.x); target.setY(pointF.y); // 這裡順便做一個alpha動畫 target.setAlpha(1 - animation.getAnimatedFraction()); } } private class AnimEndListener extends AnimatorListenerAdapter { private View target; public AnimEndListener(View target) { this.target = target; } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //因為不停的add 導致子view數量只增不減,所以在view動畫結束後remove掉 removeView((target)); } } }
在Activity中:<com.sxs.huoshanvideo.widgt.widget.FavorLayout android:id="@+id/fly" android:layout_marginTop="550px" android:layout_marginLeft="350px" android:layout_width="400px" android:layout_height="500px"> </com.sxs.huoshanvideo.widgt.widget.FavorLayout>
final FavorLayout fl = (FavorLayout) findViewById(R.id.fl);
fl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fl.addHeart();
}
});