平时业务基本不涉及动画,这里记录下动画的学习收获
属性动画:根据View的属性去做动画,逐渐的一点一点的去改变View的属性。其动画默认时长是300ms,默认帧率是10ms/帧。
使用示例:
public class MainActivity extends BaseActivity {
CircleView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (CircleView) findViewById(R.id.image_view);
// 用系统自带做动画非常方便,但仅限于几种简单的动画
// 比如说translationX,就是不断的对X进行值的填入,慢慢把X变大
// 例如:view.setTranslationX(20);(10ms之后)
// view.setTranslationX(40);(20ms之后)
// view.setTranslationX(70);(30ms之后)
// view.setTranslationX(100);(40ms之后)
view.animate()
.translationX(UiUtils.dpToPixel(200))
.setStartDelay(1000) // 延迟1秒后执行,便于观察
.start();
}
}
例子非常简单,就是对View的X属性进行改变。
在看下另外一种属性动画ObjectAnimator:
// 会通过反射去调用setRadius()和getRadius;
// 仅仅会改变radius的值,但onDraw不会主动调用,所以要这对应方法里加上invalidate()
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"radius",UiUtils.dpToPixel(150));
animator.setStartDelay(1000);
animator.start();
ObjectAnimator是通过反射来获取到属性的值,其会调用对应的方法。
对应的CircleView就得补上对应的方法:
public class CircleView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float radius = UiUtils.dpToPixel(50);
public CircleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
paint.setColor(Color.RED);
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
// 不要少加这块代码,否则不会自动变大
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
}
}
如果漏了invalidate(),则仅仅会改变radius的属性,但不会重新绘制,所以也不会有动画效果。
再说下AnimatorSet
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(view, "radius1", UiUtils.dpToPixel(150)),
ObjectAnimator.ofFloat(view, "radius2", UiUtils.dpToPixel(150))
);
set.setDuration(5 * 1000).start();
其实套路和ObjectAnimator基本一样,就是可以让多个属性同时改变。