ValueAnimator:通过不断控制值的变化,在不断手动的赋给对象的属性,从而实现动画的效果
ValueAnimator 的常用方法:
ValueAnimator.ofInt(int values) ValueAnimator.ofFloat(float value) ValueAnimator.ofObject(int values)
废话不多哔哔 直接开始
ValueAnimator.ofInt(int values)的使用
首先看一下源码熟悉一下
public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
源码很简单 就是将值赋给了ValueAnimator 这个对象
简单的demo:
private Button btn;
private ValueAnimator valueAnimator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animator_text);
btn = findViewById(R.id.haha);
valueAnimator = ValueAnimator.ofInt(btn.getLayoutParams().width,300);
valueAnimator.setDuration(1500);//时间时长
// 设置动画延迟播放时间
valueAnimator.setStartDelay(500);
// 设置动画重复播放次数 = 重放次数+1
// 动画播放次数 = infinite时,动画无限重复
valueAnimator.setRepeatCount(2);
// 设置重复播放动画模式
// ValueAnimator.RESTART(默认):正序重放
// ValueAnimator.REVERSE:倒序回放
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
// 数值每次变化更新都会调用该方法
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
int currentValue = (Integer) animator.getAnimatedValue();
// 获得每次变化后的属性值
btn.getLayoutParams().width = currentValue;
// 每次值变化时,将值手动赋值给对象的属性
// 步骤4:刷新视图,即重新绘制,从而实现动画效果
btn.requestLayout();
}
});
valueAnimator.start();
// 启动动画
}
layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AnimatorText">
<Button
android:id="@+id/haha"
android:layout_width="80dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:text="哈哈"
/>
</RelativeLayout>
ValueAnimator.ofFloat() 和ofInt()使用方法相似 在这里就不多做使用
然后直接上本次的重点 ValueAnimator.ofObject();
同样的 我们先来看一下源码:
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
其中的第一个参数为TypeEvaluator(估值器):数值具体变化过程的当前数值
然后我们看一下估值器的源码:
public interface TypeEvaluator<T> {
//fraction -> 从开始到结束的分数(占比)
//startValue ->起始值
//endValue ->结束值
public T evaluate(float fraction, T startValue, T endValue);
}
也很简单 就是一个接口 里面有一个方法
要想使用ValueAnimator.ofObject()我们就需要实现TypeEvaluator的接口
这就要根据你的业务需求进行设置,这里就上一个demo:(TypeEvaluator的实现类重写的方法中需要传的都是对象 而不是数值 )
1.Point类:
public class Point {
public Point(float x, float y) {
this.x = x;
this.y = y;
}
private float x;
private float y;
public float getX() {
return x;
}
public float getY() {
return y;
}
}
2.定义PointEvaluator类实现TypeEvaluator接口
public class PointEvaluator implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
Point start = (Point) startValue;
Point end = (Point) endValue;
float x = start.getX() + fraction * (end.getX() - start.getX());
float y = start.getY() + fraction * (end.getY() - start.getY());
Point point = new Point(x,y);
return point;
}
}
3.简单的实现:
Point point1 = new Point(0, 0);
Point point2 = new Point(300, 300);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), point1, point2);
anim.setDuration(5000);
anim.start();
4.自当以View实现小球下滑功能
public class TryText extends View {
public static final float RADIUS = 50f;
private Point currentPoint;
private Paint mPaint;
public TryText(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas) {
if (currentPoint == null) {
currentPoint = new Point(RADIUS, RADIUS);
drawCircle(canvas);
startAnimation();
} else {
drawCircle(canvas);
}
}
private void drawCircle(Canvas canvas) {
float x = currentPoint.getX();
float y = currentPoint.getY();
canvas.drawCircle(x, y, RADIUS, mPaint);
}
private void startAnimation() {
//确定起始值和结束值
Point startPoint = new Point(RADIUS, RADIUS);
Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);
Log.i("haonanguo","@"+getWidth());
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
invalidate();
}
});
anim.setDuration(5000);
anim.start();
}
}
效果图:
这里也很简单 确定好起始值和结束值后 然后调用invalidate一直改变小球的坐标就ok
关于TypeEvaluator 也可以去参考FloatEvaluator的源码以及IntEvaluator的源码