Android动画机制-属性动画(二)
在上一节Android动画机制-属性动画(一)我们简单的运用了系统给的api来完成动画,这个玩点大的。
万能动画
ofXXX的底层其实用到反射调用View中的setXXX,比如把translation写成translate那么就会报错:
因此万能的数值发生器有两种思路:
一种是使用ObjectAnimator,提供属性的setXXX和getXXX,另外一种是使用ValueAnimator
仿照小米清理垃圾的动画
在这里就用两种方式实现
使用ObjectAnimator
由于想要画出一个圆形,但是坐标太难计算,所以使用旋转canvas的思路
public class DrawCircle extends View {
// 设置canvas的旋转角度
private float degress;
public DrawCircle(Context context) {
super(context);
}
public DrawCircle(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStrokeWidth(8);
float width = canvas.getWidth();
float height = canvas.getHeight();
float radius = width / 4;
canvas.translate(width / 2, height / 2);
// 写出正在清理垃圾请稍等
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setTextSize(25);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("正在清理垃圾请稍等", 0, 0, paint);
// 画出圆形
paint.setColor(Color.RED);
for (float i = 0; i < degress; i += 0.01) {
canvas.rotate(i);
canvas.drawPoint(0, -radius, paint);
}
}
// 两个包装方法
public float getDegress() {
return degress;
}
public void setDegress(float degress) {
this.degress = degress;
}
Activity中的实现代码:
ObjectAnimator animator = new ObjectAnimator().ofFloat(mDrawCircle, "degress", 0, 360);
animator.setDuration(120000);
//设置一个线性差速器
animator.setInterpolator(new LinearInterpolator());
//添加一个监听器
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//通知View重绘也就是调用onDraw方法
mDrawCircle.postInvalidate();
}
});
animator.start();
使用ValueAnimator
自定义view完全一样,Activity中的实现:
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 360);
//设置作用的目标
valueAnimator.setTarget(mDrawCircle);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(120000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//得到角度
float degress = (float) animation.getAnimatedValue();
mDrawCircle.setDegress(degress);
//通知重绘
mDrawCircle.postInvalidate();
}
});
valueAnimator.start();
核心思想都是一样的只不过就是使用ValueAnimator是通过在监听器中的到的角度
把自定义View和动画结合
public class DrawCircle extends View {
// 设置canvas的旋转角度
private float degress;
// 设置自带的动画
private ValueAnimator mAnimator;
public DrawCircle(Context context) {
super(context);
initAnimator();
}
public DrawCircle(Context context, AttributeSet attrs) {
super(context, attrs);
initAnimator();
}
public DrawCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAnimator();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStrokeWidth(8);
float width = canvas.getWidth();
float height = canvas.getHeight();
float radius = width / 4;
canvas.translate(width / 2, height / 2);
// 写出正在清理垃圾请稍等
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setTextSize(25);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("正在清理垃圾请稍等", 0, 0, paint);
// 画出原型
paint.setColor(Color.RED);
for (float i = 0; i < degress; i += 0.01) {
canvas.rotate(i);
canvas.drawPoint(0, -radius, paint);
}
}
// 两个包装方法
public float getDegress() {
return degress;
}
public void setDegress(float degress) {
this.degress = degress;
}
public void startAnimator(){
// 防止重复播放动画
mAnimator.cancel();
mAnimator.start();
}
/**
* 初始化动画
*/
private void initAnimator() {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 360);
valueAnimator.setTarget(this);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(120000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float degress = (float) animation.getAnimatedValue();
setDegress(degress);
invalidate();
}
});
mAnimator = valueAnimator;
}
这样只要在Avtivity中调用startAnimator即可
属性动画的核心就是一个数值发生器
在规定时间内的数值变化就形成了动画
作者官方博客:天意博文
更多好玩文章:Android动画机制-传统动画