ValueAnimator和TypeEvaluator 的使用

来源:互联网 发布:淘宝运营新手好学吗 编辑:程序博客网 时间:2024/06/02 05:11
属性值=f( g(a) ,b ,c )f(...):代表TypeEvaluator:插值g(a):代表TimeInterpolator:插值的时间点b: 起始属性值c:  结束属性值


TimeInterpolator:获取动画的进度时间(时间可以不均匀变化):

比如:一个动画执行100秒,属性值相对应0到100(随进度均匀),
TimeInterpolator可以控制现实中度过一秒时,动画就执行了十秒;
也可以控制现实中度过80秒时属性值已经到达100,然后回属性值再回退到90。


TypeEvaluator:获取动画的属性值(属性值随当前的进度而变化,可以不均匀变化)

比如:一个动画执行100秒,属性值可以正弦sin(t)变化,也可以线性变化。

参考:ViewPropertyAnimator的使用

一、相关API:

获取ValueAnimator

public static ValueAnimator ofArgb(int... values)public static ValueAnimator ofFloat(float... values)public static ValueAnimator ofInt(int... values)public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values)public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {    ValueAnimator anim = new ValueAnimator();    anim.setObjectValues(values);    anim.setEvaluator(evaluator);    return anim;}

设置ValueAnimator

public ValueAnimator setDuration(long duration)public void setTarget(Object target)public void setRepeatCount(int value)public void setRepeatMode(@RepeatMode int value)public void setStartDelay(long startDelay) public void setInterpolator(TimeInterpolator value)public void setEvaluator(TypeEvaluator value)public void setIntValues(int... values)public void setFloatValues(float... values) public void setObjectValues(Object... values)public void setValues(PropertyValuesHolder... values)//获取当前进度值public Object getAnimatedValue()//启动public void start() 

监听ValueAnimator

public void addListener(AnimatorListener listener) //可选择实现public void addPauseListener(AnimatorPauseListener listener)public void addUpdateListener(AnimatorUpdateListener listener)//AnimatorListenerAdapter包含AnimatorListener,AnimatorPauseListener//抽象类可以选择实现public abstract class AnimatorListenerAdapter implements                                                 Animator.AnimatorListener,                                                 Animator.AnimatorPauseListener{...}public static interface AnimatorListener {    void onAnimationStart(Animator animation);    void onAnimationEnd(Animator animation);    void onAnimationCancel(Animator animation);    void onAnimationRepeat(Animator animation);}public static interface AnimatorPauseListener {    void onAnimationPause(Animator animation);    void onAnimationResume(Animator animation);}public static interface AnimatorUpdateListener {    void onAnimationUpdate(ValueAnimator animation);}

二、示例:

示例效果:

小圆沿着正弦曲线不断运动

PointSinView

public class PointSinView extends View {    private static final int RADIUS = 20;    private Point currentPoint;    private Paint paint;    private Point startP;    private Point endP;    public PointSinView(Context context) {        this(context, null);    }    public PointSinView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public PointSinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        paint = new Paint();        paint.setAntiAlias(true);        paint.setColor(Color.RED);        paint.setStrokeWidth(10);        paint.setStyle(Paint.Style.FILL);        paint.setDither(true);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        startP = new Point(RADIUS, getHeight() / 2);//初始值(起点)        endP = new Point(getWidth() - RADIUS, getHeight() / 2);//结束值(终点)        currentPoint = startP;    }    Handler handler = new Handler();    public void start() {        handler.postDelayed(runnable, 100);    }    Runnable runnable = new Runnable() {        @Override        public void run() {            final ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointSinEvaluator(), startP, endP);            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                @Override                public void onAnimationUpdate(ValueAnimator animation) {                    currentPoint = (Point) animation.getAnimatedValue();                    postInvalidate();                }            });            valueAnimator.setDuration(5000);            valueAnimator.start();            handler.postDelayed(this, 5000);        }    };    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawPoint(currentPoint.x, currentPoint.y, paint);    }}

PointSinEvaluator :决定值

public class PointSinEvaluator implements TypeEvaluator {    @Override    public Object evaluate(float fraction, Object startValue, Object endValue) {        Point startPoint = (Point) startValue;        Point endPoint = (Point) endValue;        int x = (int) (startPoint.x + fraction * (endPoint.x - startPoint.x));        int y = (int) ((float) (Math.sin(x * Math.PI / 180) * 100) + endPoint.y / 2);        return new Point(x, y);    }}

布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="启动动画" />    <com.joanzapata.android.PointSinView        android:id="@+id/pointsin"        android:layout_width="match_parent"        android:layout_height="300dp"        android:background="#e5e5e5" /></LinearLayout>

MyActivityI

public class MyActivityI extends AppCompatActivity {    private PointSinView pointSin;    private Button btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_anim);        btn = ((Button) this.findViewById(R.id.btn));        pointSin = ((PointSinView) this.findViewById(R.id.pointsin));        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                pointSin.start();            }        });    }}