视图动画只改变显示,不能响应事件,当某个元素发生视图动画后,其响应事件的位置依然在动画前的位置。
Animation:视图动画框架
Animator:属性动画框架
Animator框架中使用最多的AnimatorSet和ObjectAnimator配合。
使用ObjectAnimator进行更精细化的控制,只控制一个对象的一个属性值;使用多个ObjectAnimator组合到AnimatorSet形成一个动画。
ObjectAnimator能够自动驱使,可以设置setFrameDelay()设置动画帧之间的时间间隔、调整帧率、减少动画过程中的频繁绘制,在不影响动画效果的前提下,减少CPU的资源消耗。
属性动画通过调用属性的set get 方法,真实的控制一个View的属性值,基本可以实现所有的动画。
简单的属性动画
private void simpleAnimator(View v) {
x += 300;
ObjectAnimator animator = ObjectAnimator.ofFloat(v, "translationX", x);
animator.setDuration(500);
animator.setInterpolator(new OvershootInterpolator());
animator.start();
}
第三个参数是可变数组参数,传进去的是给该属性变化的一个取值过程,与视图动画一样,属性动画也可以设置显示时长,差值器。
在使用ObjectAnimator的时候,最终要的就是:要操纵的属性必须有get、set方法,不然ObjectAnimator无法起作用。
常用的可以直接使用的属性动画的属性值:
translationX、translationY:控制view从布局容器左上角的坐标开始的位置。
rotation、rotationX、rotationY:控制view对象绕支点进行2D、3D旋转。
scaleX、scaleY:控制view对象绕着支点进行2D缩放。
pivotX、pivotY:控制view对象的支点,默认是view的中心。
x、y:描述view对象在它的容器中的最终位置,是最初左上角坐标和translationX、translationY的值得累计和。
alpha:控制view对象的透明度,默认1。
一个属性如果没有提供get、set方法的解决方案:
1、通过自定义一个属性类或者包装类,来间接的给这个属性增加get、set方法。
public class WrapperView {
private View mTarget;
public WrapperView(View target) {
mTarget = target;
}
public int getWidth() {
return mTarget.getLayoutParams().width;
}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
public int getHeight() {
return mTarget.getLayoutParams().height;
}
public void setHeight(int height) {
mTarget.getLayoutParams().height = height;
mTarget.requestLayout();
}
}
使用的时候操作包装类:
private void wrapperAnimator() {
WrapperView wrapperView = new WrapperView(mImage);
ObjectAnimator animator = ObjectAnimator.ofInt(wrapperView, "width", (int) (mDensity * 330 + 0.5));
animator.setDuration(1000);
animator.start();
ObjectAnimator animator2 = ObjectAnimator.ofInt(wrapperView, "height", (int)
(mDensity * 440 + 0.5));
animator2.setDuration(1000);
animator2.start();
}
2、通过ValueAnimator实现。
ValueAnimator是属性动画的核心,ObjectAnimator继承自ValueAnimator。
ValueAnimator本身并不提供任何动画,它更像一个数值发生器,用来产生具有一定规律的数字,从而让调用者来控制动画的实现过程。
private void valueAnimator(){
ValueAnimator animator = ValueAnimator.ofFloat(0,600);
animator.setTarget(mImage);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mImage.getLayoutParams();
params.topMargin = (int)value;
mImage.setLayoutParams(params);
}
});
animator.start();
}
动画时间监听:
一个完整的动画包括start、repeat、end、cancel四个过程。有两个监听的实现:
1、AnimatorListener接口
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
2、AnimatorListenerAdapter抽象类:
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}
});