ValueAnimator详解

Android动画共分为两种:View Animation(视图动画)和Property Animator(属性动画)

  • View Animation 包括 Tween Animation(补间动画)和 Frame Animation(逐帧动画)
  • Property Animator 包括 ValueAnimator 和 ObjectAnimation

View Animation 和 Property Animator的区别:

区别 View Animation Property Animator
引入时间 API Level 1 API Level 11
所在包名 android.view.animation android.animation
命名 XXXXAnimation XXXXAnimator
作用对象 控件 控件属性




这里以TranslateAnimation位移动画为例,补间动画改变的只是控件的显示位置,没有改变控件的实际位置。这个过程是由Parent View来实现的,在View被绘制时,Parent View改变View的 绘制参数,这个View就会发生对应的位移动画,但是View的实际参数并没有改变。对应的View在移动过程中和移动后是没有点击效果的,然而在View原来的点击区域,可能此时已经不可见,但是仍然可以有点击效果。属性动画就恰恰相反,属性动画是通过改变控件的内部属性值来实现动画效果。


简单使用:

ValueAnimator详解_第1张图片
这里写图片描述

 valueAnimator = ValueAnimator.ofInt(10,800);
          valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(ValueAnimator animation) {
                  int value = (int) animation.getAnimatedValue();
                  tv.setText("值:"+value);
                  img.layout((int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,16,getResources().getDisplayMetrics())+value), (int) img.getY(),
                          (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,16,getResources().getDisplayMetrics())+value+img.getWidth()),(int) img.getY()+img.getHeight());//坐标以父控件为基准
              }
          });
          valueAnimator.setDuration(1000);
          valueAnimator.start();

基本的的api使用,请查看api文档,这里我们将一些别的。


取消监听的方法

 /*
  * 移除 AnimatorUpdateListener
  */
  void removeUpdateListener(AnimatorUpdateListener listener);
  void removeAllUpdateListeners();
   /*
    * 移除 AnimatorListener
    */
  void removeListener(AnimatorListener listener);
  void removeAllListeners();
  /*
   * 延时多久时间开始,单位是毫秒
   */
  public void setStartDelay(long startDelay)
  /*
   * 完全克隆一个 ValueAnimator 实例,包括它所有的设置以及所有对监听器代码的处理
   * 就像克隆羊一样,克隆羊拥有母体所有的特征,但是完成克隆之后,就是新的生命体,跟母体也就没有任何关系了
   */
  public ValueAnimator clone()

Evaluator计算器

ValueAnimator详解_第2张图片
这里写图片描述

Evaluator其实就是一个转换器,将小数进度转换成对应的数值。Evaluator都是专用的,比如ofInt(int...),那么对应的Evaluator必然要返回int类型的值,否则就会报强转的错误。valueAnimator.setEvaluator()来设置转换器.


IntEvaluator源码:

public class IntEvaluator implements TypeEvaluator {
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }
}

其中 fraction 就是插值器中的返回值,表示当前动画的数值进度,百分制的小数表示。 startValue 和 endValue 分别对应 ofInt(int start,int end)中的 start 和 end 的数值;

自定义Evaluator

public class MyEvaluator implements TypeEvaluator {
    @Override
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(200+startInt + fraction * (endValue - startInt));
    }
}

所以我们可以通过自定义插值器改变数值进度来改变数值位置,也可以通过自定义Evaluator改变进度所对应数值来改变数值位置。

ArgbEvaluator色值过渡计算器

例子:

 valueAnimator = ValueAnimator.ofInt(0xfff10f0f,0xfff10fbf,0xff740ff1,0xff2f0ff1,0xff0f94f1,0xff0ff1af,0xff14f10f,0xffeaf804,0xfff92a0f);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                img.setBackgroundColor(value);
            }
        });
        valueAnimator.setDuration(6000);
        valueAnimator.setEvaluator(new ArgbEvaluator());
        valueAnimator.start();

效果:

ValueAnimator详解_第3张图片
这里写图片描述



源码:

public class ArgbEvaluator implements TypeEvaluator {
    private static final ArgbEvaluator sInstance = new ArgbEvaluator();
    /**
     * @hide
     */
    public static ArgbEvaluator getInstance() {
        return sInstance;
    }
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        int startInt = (Integer) startValue;
        int startA = (startInt >> 24) & 0xff;
        int startR = (startInt >> 16) & 0xff;
        int startG = (startInt >> 8) & 0xff;
        int startB = startInt & 0xff;

        int endInt = (Integer) endValue;
        int endA = (endInt >> 24) & 0xff;
        int endR = (endInt >> 16) & 0xff;
        int endG = (endInt >> 8) & 0xff;
        int endB = endInt & 0xff;

        return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
                (int)((startR + (int)(fraction * (endR - startR))) << 16) |
                (int)((startG + (int)(fraction * (endG - startG))) << 8) |
                (int)((startB + (int)(fraction * (endB - startB))));
    }

色值:A R G B ,分别表示透明度,红色,绿色,蓝色,每一个色值都用十六进制来表示,0xffff0000,

色值是通过位移和运算求出的。色值和ARGB对应关系如下:

ValueAnimator详解_第4张图片
这里写图片描述

ofObject讲解

ofObject()可以实现自定义类型的动画效果

public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);

第一个是自定义的 Evaluator,第二个是可变长参数,Object 类型的


一个小例子:

ValueAnimator详解_第5张图片
这里写图片描述

自定义Evaluator

public class MyEvaluator implements TypeEvaluator {
    private static final String TAG = "MyEvaluator";
    @Override
    public String evaluate(float fraction, String startValue, String endValue) {
        int length = endValue.length();
        String result = String.valueOf(endValue.charAt((int) (fraction * (length -1))));
        return result;
    }
}
ValueAnimator animator = ValueAnimator.ofObject(new MyEvaluator(),"且品鸡汤莫问厨娘");
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                String str = (String) animation.getAnimatedValue();
                tv.setText(str);
            }
        });
        animator.setDuration(5000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();

自定义对象实例


效果图:

ValueAnimator详解_第6张图片
这里写图片描述

 private void animatorOfObjectCustom(){
        ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(),new Ponit(20),new Ponit(200));
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Ponit ponit = (Ponit) animation.getAnimatedValue();
                mCircleView.setPoint(ponit);
            }
        });
        animator.setDuration(1000);
        animator.setInterpolator(new BounceInterpolator());
        animator.start();
    }

自定义类

public class Ponit {
    private int mRadius;
    public Ponit() {
    }
    public Ponit(int mRadius) {
        this.mRadius = mRadius;
    }
    public int getRadius() {
        return mRadius;
    }
    public void setRadius(int mRadius) {
        this.mRadius = mRadius;
    }
}

自定义view

public class CircleView extends View {
    private Ponit mCurrentPoint;
    private Paint mPiant ;
    private int mScreenWidth;//屏幕宽度
    public CircleView(Context context) {
        this(context,null);
    }

    public CircleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPiant = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPiant.setColor(Color.RED);
        mPiant.setStyle(Paint.Style.FILL);
        mScreenWidth = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mCurrentPoint != null){
            canvas.drawCircle(mScreenWidth/2,getY()+getPaddingTop(),mCurrentPoint.getRadius(),mPiant);
        }
    }

    public void setPoint(Ponit point){
        this.mCurrentPoint = point;
        invalidate();
    }
}

你可能感兴趣的:(ValueAnimator详解)