一.概况
这里的“动画”是一个广义的动画,认为属性的变化过程就是动画。
1.1属性动画特点:
属性动画可以对任意的对象做动画,动画默认的时间间隔是300ms,默认帧率是10ms/帧;达到的效果是:将一个对象的属性值在一定时间内从一个值变为另一个值。
1.2兼容性
属性动画从API11才有,虽然可以使用如nineoldandroids这样的开源动画库实现向前兼容,但是在API11以前的系统上实质还是View动画。(但是现在看来大多数app已经舍弃这部分老系统的用户了,因为的确比较少了,除非像qq等很大的app可能会继续照顾这些老系统用户)
1.3本文内容
ValueAnimator,ObjectAnimator,AnimatorSet的基本用法
二.ValueAnimator
2.1简介
1.非常核心的类,但是我们平时较少用到,我们较多用到的是ObjectAnimator。因为ValueAnimator控制的是一个数值从一个初始值到终点值的变化,本身不作用于任何对象,也就没有动画效果。
2.我们设置初始值,终点值,数值变化的速度;我们还可以控制动画播放次数,播放的顺序;同时我们还可以监听到播放的进度;
2.2使用
看起来复杂用起来简单
先看效果,一个从0到500的过程
粘贴关键代码
private void startAni() {
//实例化
ValueAnimator ani = ValueAnimator.ofFloat(0f,500f);
//设置动画时间
ani.setDuration(3000);
//加监听器
ani.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
showTv.setText(value+"");
}
});
//开始
ani.start();
}
2.3其他方法
1.ofFloat和ofInt比较常见,且他们两个的用法基本相同。除此之外还有ofArgb和ofObject还有ofPropertyValuesHolder等三个方法由于涉及其他知识点放在后面的文章中解读。
2.除2.2中方法外还可以用setStartDelay设置延时播放时间;setRepeatCount()设置重复播放次数(设置大于0则为设置的次数,小于0为无限重复);setRepeatMode()设置播放顺序(RESTART从头开始播放;REVERSE倒序播放);等等还有很多,这里不一一列举,上面几个是最重要的几个。
三.ObjectAnimator
3.1简介
1.最常用的类,他和上面的ValueAnimator比较,可以操作我们平时使用的类的属性,比如最常用的View的属性。
2.它继承自ValueAnimator,底层的动画实现机制也是基于ValueAnimator来完成的,因此ValueAnimator仍然是整个属性动画当中最核心的一个类。用法和ValueAnimator肯定是非常的相似喽。
3.2简单使用
下面我们来看一下如何实现补间动画中的透明度(alpha),旋转(rotation),平移(translation),缩放(scaledon)动画。
先看图,点击头部的button,下面的TextView也就是showTv开始完成相应的动画。
透明度(alpha)
关键代码,透明度从1到0再到1
private void playAlpha() {
ObjectAnimator ani = ObjectAnimator.ofFloat(showTv,"alpha",1f,0f,1f);
ani.setDuration(5000);
ani.start();
}
旋转(rotation)
关键代码:默认围绕view的中心旋转,从0转到360在转到0;
private void playRotation() {
ObjectAnimator ani = ObjectAnimator.ofFloat(showTv,"rotation",0f,360f,0f);
ani.setDuration(5000);
ani.start();
}
平移(translation)
关键代码:x方向上平移,从现在位置向左平移400px,再向右平移回来。
private void playTranslation() {
float currentTranslationX = showTv.getTranslationX();
ObjectAnimator ani = ObjectAnimator.ofFloat(showTv,"translationX",currentTranslationX,currentTranslationX - 400,currentTranslationX);
ani.setDuration(5000);
ani.start();
}
缩放(scaledon)
关键代码:缩放,以中心线为轴从1倍伸缩到4倍,再伸缩到1倍。
private void playScale() {
ObjectAnimator ani = ObjectAnimator.ofFloat(showTv,"scaleY",1f,4f,1f);
ani.setDuration(5000);
ani.start();
}
四.组合动画
在上一篇文中我们发现了补间动画可以实现组合动画,其组合动画同时执行较简单,但是想将动画分步骤执行就要自己来通过监听上一个动画执行完接着执行下一个,说实话比较麻烦,而属性动画实现起来就很简单了;属性动画提供了丰富的api供我们调用。
先看图
代码如下,里面的代码注释很好理解
private void playSet() {
//实例化各个动画
ObjectAnimator scaleAni = ObjectAnimator.ofFloat(showTv,"scaleY",1f,4f,1f);
ObjectAnimator rotationAni =ObjectAnimator.ofFloat(showTv,"rotation",0f,360f,0f);
ObjectAnimator translationXAni = ObjectAnimator.ofFloat(showTv,"translationX",-300f,0f);
ObjectAnimator alphaAni = ObjectAnimator.ofFloat(showTv,"alpha",1f,0f,1);
//创建动画集合
AnimatorSet set = new AnimatorSet();
//设置播放的顺序
set.play(translationXAni).with(scaleAni).before(rotationAni).before(alphaAni);
//设置播放时间
set.setDuration(5000);
//开始播放
set.start();
}
五.使用xml文件实现属性动画
使用xml文件可以带来重复使用的好处,坏处就是写死了,不能灵活改变属性值。
以四中的组合动画为例
下面是java代码
private void playXMLSet() {
Animator ani = AnimatorInflater.loadAnimator(this,R.animator.four_sort_property_animator);
ani.setTarget(showTv);
ani.start();
}
属性动画xml文件four_sort_property_animator(注意这里要在res下面新建animator文件夹,并将属性动画的xml文件放在里面)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<set android:ordering="together">
<objectAnimator
android:duration="2500"
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="-300px"
android:valueTo="0px"/>
<set android:ordering="sequentially">
<objectAnimator
android:duration="1250"
android:propertyName="scaleY"
android:valueType="floatType"
android:valueFrom="1f"
android:valueTo="4f"/>
<objectAnimator
android:duration="1250"
android:propertyName="scaleY"
android:valueType="floatType"
android:valueFrom="4f"
android:valueTo="1f"/>
</set>
</set>
<set android:ordering="together">
<set android:ordering="sequentially">
<objectAnimator
android:duration="1250"
android:propertyName="rotation"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="360" />
<objectAnimator
android:duration="1250"
android:propertyName="rotation"
android:valueType="floatType"
android:valueFrom="360"
android:valueTo="0" />
</set>
<set android:ordering="sequentially">
<objectAnimator
android:duration="1250"
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="1"
android:valueTo="0"/>
<objectAnimator
android:duration="1250"
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="1"/>
</set>
</set>
</set>
上面的关键在于动画的xml文件,从中我们发现一个特点,文件很长相对于在java代码中书写,而且数值是写死的不能修改在执行的过程中。
属性动画更方便使用java代码来书写。而不是使用xml文件的方式。
六.Animator监听器
6.1addListener
我们想要监听动画的开始,结束,重复,取消用addListener()这个方法就行了。而这个方法是Animator这个抽象类的,由于ObjectAnimator继承自ValueAnimator,ValueAnimator继承自Animator且AnimatorSet也继承自Animator所以这些都可以使用这个方法。
如下
set.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) {
}
});
有时候我们只关心一个回调,而不想管别的回掉,那么我们可以使用AnimatorListenerAdapter来替换掉AnimatorListener,其实现了后者所以可以只重写自己关心的回调方法就好了。如下:
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
6.2addUpdateListener
添加实时监听器:监听整个动画过程,动画是由许多帧组成的,每播放一帧onAnimationUpdate就会回调一次,这里面我们可以做很多事情。
ani.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
});
6.3addPauseListener
添加暂停和运行监听器(注意这个是API19后添加的)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ani.addPauseListener(new Animator.AnimatorPauseListener() {
@Override
public void onAnimationPause(Animator animation) {
}
@Override
public void onAnimationResume(Animator animation) {
}
});
}
七.几个注意的方法
setRepeatCount,setRepeatMode,setStartDelay都是ValueAnimator中的,所以ObjectAnimator也可以使用。
setRepeatCount:对应xml中repeatCount属性
public void setRepeatCount(int value)
动画控制重复播放的次数,value默认为0,其中-1表示无限循环
setRepeatMode:对应xml中repeatMode属性
public void setRepeatMode(@RepeatMode int value)
动画循环的模式有两个值:
//从头播放
public static final int RESTART = 1;
//倒序播放
public static final int REVERSE = 2;
setStartDelay:对应xml中startOffset属性
public void setStartDelay(long startDelay)
动画延时播放时间:调用start之后延时startDelay播放。