屬性動畫一些基礎概念:
ViewPropertyAnimator
使⽤用 View.animate() 創建對象,以及使⽤用 ViewPropertyAnimator.translationX() 等⽅方法來設置動畫;
可以連續調⽤用來設置多個動畫;setDuration() 來設置持續時間、 setStartDelay() 來設置開始延時;
以及其他⼀一些便便捷⽅方法。
view.animate()
.translationX(Utils.dp2px(200))
.translationY(100)
.rotation(180)
.alpha(0.5f)
.setStartDelay(1000)
.start();
ObjectAnimator
使⽤用 ObjectAnimator.ofXxx() 來創建對象,以及使⽤用 ObjectAnimator.start() 來主動啓動動畫。它的優勢在於,可以爲⾃自定義屬性設置動畫。
ObjectAnimator animator = ObjectAnimator.ofObject(view, "radius",Utils.dp2px(200));
另外,⾃自定義屬性需要設置 getter 和 setter ⽅方法,並且 setter ⽅方法⾥裏里需要調⽤用 invalidate() 來觸發重繪:
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
invalidate();
}
Interpolator
插值器器,⽤用於設置時間完成度到動畫完成度的計算公式,直⽩白地說即設置動畫的速度曲線,通過setInterpolator(Interpolator) ⽅方法來設置。
PropertyValuesHolder
⽤於設置更加詳細的動畫,例如多個屬性應⽤用於同⼀個對象:
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("radius",Utils.dp2px(200));
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("offset",Utils.dp2px(100));
ObjectAnimator animator = PropertyValuesHolder.ofPropertyValuesHolder(view,holder1, holder2);
或者配合使用 Keyframe ,對一個屬性分多個段:
Keyframe keyframe1 = Keyframe.ofFloat(0, Utils.dpToPixel(100));
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, Utils.dpToPixel(250));
Keyframe keyframe3 = Keyframe.ofFloat(1, Utils.dpToPixel(200));
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("radius",keyframe1,keyframe2, keyframe3);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view,holder);
TypeEvaluator
⽤於設置動畫完成度到屬性具體值的計算公式。默認的 ofInt() ofFloat() 已經有了了自帶的IntEvaluator FloatEvaluator ,但有的時候需要⾃己設置 Evaluator。
class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
// (1, 1) (5, 5) fraction: 0.2 x: 1 + (5 - 1) * 0.2 y: 1 + (5 - 1) * 0.2
float x = startValue.x + (endValue.x - startValue.x) * fraction;
float y = startValue.y + (endValue.y - startValue.y) * fraction;
return new Point((int) x, (int) y);
}
}
另外,對於不支持的類型,也可以使用 ofObject() 來在創建 Animator 的同時就設置上Evaluator,比如 PointView:
public class PointView extends View {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Point point = new Point(0, 0);
public PointView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
paint.setStrokeWidth(Utils.dpToPixel(15));
paint.setStrokeCap(Paint.Cap.ROUND);
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPoint(point.x, point.y, paint);
}
}
在使用時:
ObjectAnimator animator = ObjectAnimator.ofObject(view, "province", new ProvinceEvaluator(), "澳門特別行政區");
animator.setDuration(10000);
animator.start();