属性动画
上一篇我们总结了补间动画,接下来我们来总结一下属性动画的用法。
自从android3.0 之后又有了属性动画PropertyAnimation。属性动画的实现机制是通过对目标对象进行赋值并修改其“属性”来实现的,这个怎么理解呢?假如我们通过属性动画来移动一个textview,那么这个textview就是真正的移动了,而不再是仅仅在另外一个位置绘制了而已,即是控件的真实位置移动了,而补间动画则是在另外一个地方绘制了一个一模一样的而已,真实位置还是在原来的地方。
ValueAnimator
ValueAnimator是整个属性动画机制当中最核心的一个类,前面我们已经提到了,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。
*ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f); *然后再开启动画即可。当然ValueAnimtor还有两个常用方法,即:ValueAnimator.ofInt(),ValueAnimator.ofObject(),除此之外,我们还可以调用setStartDelay()方法来设置动画延迟播放的时间,调用setRepeatCount()和setRepeatMode()方法来设置动画循环播放的次数以及循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思。
下边通过一个例子来介绍valueAnimator的使用:
private void vlueAnim() {
ValueAnimator anmator = ValueAnimator.ofFloat(1f, 0f, 1f, 0f);
anmator.setStartDelay(1000); //设置延时1秒后开始动画
anmator.setDuration(5000);
anmator.setRepeatCount(10);
anmator.setRepeatMode(ValueAnimator.RESTART);
anmator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
tv.setAlpha(value);//动态更新textview的透明值
}
});
anmator.start();
}
这就是在监听器中通过得到的动画值的变化来更新View的相关属性,从而有动画效果。
效果如下:
Animatorvalue.gif
ObjectAnimator
ObjectAnimator与ValueAnimator的区别:
1、构造方法与ObjectAnimator类似,ObjectAnimator继承自ValueAnimtor。
2、与ObjectAnimator的区别在于ValueAnimator构造函数的参数中不包含执行该动画“属性”信息和对象,只有动画的值变化起始值和结束值。
3、优点:结合动画更新监听onAnimationUpdate使用,可以在回调中不断更新View的多个属性,使用起来更加灵活。
ObjectAnimator可能才是我们最常接触到的类,因为ValueAnimator只不过是对值进行了一个平滑的动画过渡。而ObjectAnimator则就不同了,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。
不过虽说ObjectAnimator会更加常用一些,但是它其实是继承自ValueAnimator的,底层的动画实现机制也是基于ValueAnimator来完成的,因此ValueAnimator仍然是整个属性动画当中最核心的一个类。那么既然是继承关系,说明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的。
将textview 在3秒内,由常规变为透明再变为常规:
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "alpha", 1f, 0f, 1f);
anim.setDuration(3000);//持续时间
anim.start();
将textview 在5秒内360度旋转:
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
anim.setDuration(3000);
anim.start();
实现复合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
after(Animator anim) 将现有动画插入到该传入的动画(就是anim)之后执行
after(long delay) 将现有动画延迟指定毫秒后执行
before(Animator anim) 将现有动画插入到该传入的动画(就是anim)之前执行
with(Animator anim) 将现有动画和传入的动画同时执行
好的,有了这四个方法,我们就可以实现复合动画了,先向上平移,然后旋转同时改变透明值和缩放,就可以这样做:
private void objectAnim() {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(tv1, "alpha", 0.5f, 1f, 0.5f, 1f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(tv1, "scaleY", 1f, 3f, 1f);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationY", 0f, -100f); //Y轴平移
// ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationX", 0f, 50f); //X轴平移
AnimatorSet animset = new AnimatorSet(); //定义一个AnimatorSet对象
animset.play(anim1).with(anim2).with(anim3).after(anim4); //先执行anim4,再同时执行anim1、anim2、anim3
animset.setDuration(6000);
animset.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//动画开始,do sthing...
}
@Override
public void onAnimationEnd(Animator animation) {
//动画结束,do sthing...
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
// animset.setInterpolator(new OvershootInterpolator());
animset.start();
}
效果如下:
ObjectAnimator.gif在很多时候,我们希望可以监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理。这个功能是完全可以实现的,Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。
大家已经知道,ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法的。另外AnimatorSet也是继承自Animator的,因此addListener()这个方法算是个通用的方法。属性动画的基本用法就是这些了.不仅补间动画可以使用插值器,当然属性动画也可以加入插值器动画。
加入插值器:
TranslateAnimation down = new TranslateAnimation(0, 0, -300, 0);//位移动画,从button的上方300像素位置开始
down.setFillAfter(true);//设置动画固定结束后位置
down.setInterpolator(new BounceInterpolator()); //弹跳动画,要其它效果的当然也可以设置为其它的值
down.setDuration(2000); //持续时间
btn_login.startAnimation(down);
btn_register.startAnimation(down);
效果如下:
加入插值器.gif
更多插值器的用法可以用时候在慢慢了解。。。