android view-贝塞尔曲线应用实例

来源:互联网 发布:古城户外淘宝店 编辑:程序博客网 时间:2024/05/29 14:55

在一个Launcher的开发总因为冒泡特效引入了贝塞尔曲线应用,这里贴出源码分享下:


package com.android.bytfplauncher.view;
import java.util.ArrayList;
import java.util.Random;
import javax.crypto.AEADBadTagException;
import com.android.bytfplauncher.R;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Interpolator;
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.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class FpPeriscopeView extends RelativeLayout{
 private LinearInterpolator   line = new LinearInterpolator();
 private AccelerateInterpolator acc = new AccelerateInterpolator();
 private DecelerateInterpolator dec = new DecelerateInterpolator();
 private AccelerateDecelerateInterpolator accdec = new AccelerateDecelerateInterpolator();
 
 private int mHeight;
    private int mWidth;
    private LayoutParams lp;
    private Drawable[] drawables;
    private Random random = new Random();
   
    private int dHeight;
    private int dWidth;
 
 public FpPeriscopeView(Context context, AttributeSet attrs,
   int defStyleAttr, int defStyleRes) {
  super(context, attrs, defStyleAttr, defStyleRes);
  // TODO Auto-generated constructor stub
  init();
 }
 
 public FpPeriscopeView(Context context, AttributeSet attrs,
   int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  // TODO Auto-generated constructor stub
  init();
 } 
 public FpPeriscopeView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  init();
 } 
 
 public FpPeriscopeView(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
  init();
 }  
 
 private void init(){
  drawables = new Drawable[3];
  drawables[0] = getResources().getDrawable(R.drawable.red_pop);
  drawables[1] = getResources().getDrawable(R.drawable.greed_pop);
  drawables[2] = getResources().getDrawable(R.drawable.yerrow_pop);
  dHeight = getResources().getDrawable(R.drawable.red_pop).getIntrinsicHeight();
  dWidth = getResources().getDrawable(R.drawable.red_pop).getIntrinsicWidth();
  
  lp = new LayoutParams(dWidth, dHeight);
  lp.addRule(CENTER_HORIZONTAL);
  lp.addRule(ALIGN_PARENT_BOTTOM);
  
 }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  // TODO Auto-generated method stub
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mWidth = getMeasuredWidth();
  mHeight = getMeasuredHeight();
 }
 
 public void addHeart(){
  ImageView imageview = new ImageView(getContext());
  imageview.setImageDrawable(drawables[random.nextInt(3)]);
  imageview.setLayoutParams(lp);
  addView(imageview);
  
  Animator set = getAnimator(imageview);
        set.addListener(new AnimEndListener(imageview));
        set.start(); 
       
 }
 
  private class AnimEndListener extends AnimatorListenerAdapter {
         private View target;
 
         public AnimEndListener(View target) {
             this.target = target;
         }
 
         @Override
         public void onAnimationEnd(Animator animation) {
             super.onAnimationEnd(animation);
             removeView((target));
         }
     } 
 
 private Animator getAnimator(View target){
  AnimatorSet set = getEnterAnimtor(target);
  ValueAnimator Briz = getBezierValueAnimator(target);
  
  AnimatorSet finalset = new AnimatorSet();
  finalset.playSequentially(set);
  finalset.playSequentially(Briz);
  
  int index = random.nextInt(4);
  switch(index){
   case 0:
    finalset.setInterpolator(line);
    break;
    
   case 1:
    finalset.setInterpolator(acc);
    break;
    
   case 2:
    finalset.setInterpolator(dec);
    break;
    
   case 3:
    finalset.setInterpolator(accdec);
    break;
    
   default:
    finalset.setInterpolator(accdec);
    break;
  }
  
  finalset.setTarget(target);
        return finalset;
 }
 
 
 
 private AnimatorSet getEnterAnimtor(View target){
  ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f, 1f);
  ObjectAnimator scanx = ObjectAnimator.ofFloat(target, View.SCALE_X, 0.2f, 1f);
  ObjectAnimator scany = ObjectAnimator.ofFloat(target, View.SCALE_Y, 0.2f, 1f);
  
  AnimatorSet set = new AnimatorSet();
  set.setDuration(500);
  set.setInterpolator(new LinearInterpolator());
  set.playTogether(alpha, scanx, scany);
  set.setTarget(target);
  return set;
 }
 
  private PointF getPointF(int scale) {
  
         PointF pointF = new PointF();
         pointF.x = random.nextInt(400);
         pointF.y = random.nextInt(100) / scale;
         return pointF;
     }
 
  private class BezierEvaluator implements TypeEvaluator<PointF> {
  
      private PointF pointF1;
      private PointF pointF2;
  
      public BezierEvaluator(PointF pointF1, PointF pointF2) {
          this.pointF1 = pointF1;
          this.pointF2 = pointF2;
      }
    
      @Override
      public PointF evaluate(float time, PointF startValue, PointF endValue) {
  
          float timeLeft = 1.0f - time;
          PointF point = new PointF();// 结果
  
          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;
      }
 } 
 
 private ValueAnimator getBezierValueAnimator(View target) {
  
        // 初始化一个贝塞尔计算器- - 传入
        BezierEvaluator evaluator = new BezierEvaluator(getPointF(2),
                getPointF(1));
 
        // 这里最好画个图 理解一下 传入了起点 和 终点
        ValueAnimator animator;
       
        int index = random.nextInt(2);
        if(index == 1){
         animator =         ValueAnimator.ofObject(evaluator, new PointF((350),50),
                    new PointF(350 + random.nextInt(200), 0));
        }else{
         animator =         ValueAnimator.ofObject(evaluator, new PointF((300),50),
                    new PointF(random.nextInt(300), 0));         
        }
       

       
        animator.addUpdateListener(new BezierListenr(target));
        animator.setTarget(target);
        animator.setDuration(3000);
        return animator;
    } 
 
 private class BezierListenr implements ValueAnimator.AnimatorUpdateListener {
  
        private View target;
 
        public BezierListenr(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动画
            target.setAlpha(1 - animation.getAnimatedFraction());
        }
    } 
}

0 0
原创粉丝点击