ValueAnimator和TypeEvaluator 的使用

属性值=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();
            }
        });

    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值