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的源碼