ValueAnimator详解

来源:互联网 发布:证券分析软件 编辑:程序博客网 时间:2024/06/04 19:45

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 = 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计算器

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

IntEvaluator源码:

public class IntEvaluator implements TypeEvaluator<Integer> {    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<Integer> {    @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();

效果:
这里写图片描述

源码:

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对应关系如下:
这里写图片描述

ofObject讲解

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

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

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

一个小例子:
这里写图片描述
自定义Evaluator

public class MyEvaluator implements TypeEvaluator<String> {    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();

自定义对象实例

效果图:
这里写图片描述

 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();    }}
原创粉丝点击