Android 动画 —— 属性动画

属性动画是API 11新加入的特性,和View动画不同,它对作用的对象进行了扩展,属性动画可以对任何对象做动画,甚至还可以没有对象。属性动画对View做动画原理是,是改变View的某个属性,就是通过这个属性的set方法不断的改变这个属性的值,所以这个属性必须要有set方法,当动画没有为这个属性赋初始值时,需要get方法获得属性的初始值。属性动画的默认每10ms变化一帧,duration默认为300ms。属性动画的内部实现过程这里不做讲解,属性实现过程很多人都说过,这里只讲用法。

属性动画与渐变动画的比较

渐变动画并没有真的改变View,View的所有属性都没变,比如你用渐变动画做平移动画,实际上View的位置并没有发生,渐变动画实际上View的影像做动画。这样会造成一些问题,比如你平移了一个View,在新位置你不会触发点击事件,但在原来的位置会触发点击事件。而属性动画不会,属性动画做平移后,View就在新位置了,不会发生上面的时情。

ObjectAnimator

objectAnimator的xml用法示例

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/accelerate_decelerate"
    android:valueFrom="0"
    android:valueTo="300"
    android:valueType="floatType"
    android:propertyName="X"
    android:duration="2000">
</objectAnimator>

在代码中需这样调用

ObjectAnimator objectAnimator = 
(ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.trans_right);
objectAnimator.setTarget(animImg);
objectAnimator.start();

objectAnimator的代码用法示例

ObjectAnimator objectAnimator = 
ObjectAnimator.ofInt(animImg, "translationX", 0, 300);
objectAnimator.addListener(this);
objectAnimator.start();

这个动画实现的就是把View向右平移了300px的距离。这里有一个地方要注意,我是通过改变View的X属性,和translationX属性来改变View的位置。这两个属性(还有很多属性)是在Android 3.0(API 11)开始出现的,View为它们提供了get/set方法。x,y是View的左上角相对于父容器的坐标,translationX,translationY也是相对于父容器的坐标,默认值为0。它们之间的关系
x = left + translationX其中left为View的左上角的横坐标,left值可以通过getLeft()获得,该值也是相对于父容器的。
这是Android为我们提供了这些属性,如果要用改变View的宽度怎么实现呢?当然可以用scaleX这个属性实现,那么除了这个呢,View的width可没有get/set方法,我们又不能去更改View类为View的width属性增添get/set方法,那么还有没有其他方法呢?那就是把我们的对象包装,间接提供get/set方法。
代码示例

private static class ViewWrapper {
        private View mTarget;
        public ViewWrapper(View target) {
            mTarget = target;
        }
        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }
        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
}

这样就可以用属性动画改变View的宽了。

ValueAnimator

ValueAnimator用法示例

ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(5000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    Random random = new Random();
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
         //animation.getAnimatedValue()可以获取当前animation变化到的值
         animImg.setTranslationX((random.nextFloat() - 0.5f) 
         * animImg.getWidth() * 0.05f);
         animImg.setTranslationY((random.nextFloat() - 0.5f)
         * animImg.getHeight() * 0.05f);
    }
});
animator.start();

ValueAnimatorbu本身不作用于任何对象,但它可以让一个值在一个范围内变换,然后我们用addUpdateListener方法监听这个值得变化过程,我们可以通过animation.getAnimatedValue()获取这个值并使用它,也可以不使用,只是在这个过程中改变对象的属性。

ViewPropertyAniamtor

This class enables automatic and optimized animation of select properties on View objects. If only one or two properties on a View object are being animated, then using an{@link android.animation.ObjectAnimator} is fine; the property setters called by ObjectAnimator are well equipped to do the right thing to set the property and invalidate the view appropriately. But if several properties are animated simultaneously, or if you just want a more convenient syntax to animate a specific property, then ViewPropertyAnimator might be more well-suited to the task.

这个类不是继承与Animator类,上面这段英文是ViewPropertyAnimator的类注释,说如果你只是对View的一两个属性做动画,用ObjectAnimator那是好的,但是如果你对View的好几个属性做动画,用ViewPropertyAnimator更好。

ViewPropertyAnimator用法示例

ViewPropertyAnimator vpa = animImg.animate();
vpa.alpha(1);
vpa.rotation(720);
vpa.scaleX(0.5f);
vpa.scaleY(0.5f);
vpa.translationY(0);
vpa.setDuration(1000);
vpa.setInterpolator(new AccelerateDecelerateInterpolator());//ViewPropertyAnimator不需要通过start()来启动动画。当viewPropertiesTest()函数执行完,返回UI线程时,自动启动动画。

PropertyValuesHolder

This class holds information about a property and the values that that property should take on during an animation. PropertyValuesHolder objects can be used to create animations with ValueAnimator or ObjectAnimator that operate on several different properties in parallel.

上面这段英文为PropertyValuesHolder类的注释,这个类可以保存动画期间的属性的名称和对应值得信息,PropertyValuesHolder对象可以和ValueAnimator或者ObjectAnimator一起创建并行操控几个属性的动画。这个也能几个属性一起实现动画,但ViewPropertyAnimator更好。

PropertyValuesHolder代码示例

PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("alpha", 1);
PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("rotation", 720);
PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("scaleX", 0.5f);
PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("scaleY", 0.5f);
PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("translationY", 200, 0);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(animImg, vhAlpha, vhRoate, vhScaleX, vhScaleY, vhTrans);
animator.setDuration(1000);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.start();

Keyframe

This class holds a time/value pair for an animation. The Keyframe class is used by {@link ValueAnimator} to define the values that the animation target will have over the course of the animation. As the time proceeds from one keyframe to the other, the value of the target object will animate between the value at the previous keyframe and the value at the next keyframe. Each keyframe also holds an optional {@link TimeInterpolator} object, which defines the time interpolation over the intervalue preceding the keyframe.

上面这段英文是Keyframe类的注释,这个类持有一个动画的一个时间/值对,动画对象的属性值会从前一帧的值变到下一帧的值,每一帧也持有一个可选的TimeInterpolator(插值器)对象。

Keyframe代码示例

Keyframe keyframe0 = Keyframe.ofFloat(0.2f, 0.8f);
Keyframe keyframe1 = Keyframe.ofFloat(0.4f, 0.3f);
Keyframe keyframe2 = Keyframe.ofFloat(0.6f, 0.7f);
Keyframe keyframe3 = Keyframe.ofFloat(0.8f, 0.1f);
Keyframe keyframe4 = Keyframe.ofFloat(1.0f, 1.0f);

PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("alpha", keyframe0, keyframe1, keyframe2, keyframe3, keyframe4);
ObjectAnimator obanim = ObjectAnimator.ofPropertyValuesHolder(animImg, propertyValuesHolder);
obanim.setDuration(1000);
obanim.start();

下篇讲插值器,估值器,LayoutTransition。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值