属性动画集合:AnimatorSet
前面学习了属性动画ValueAnimator和ObjectAnimator。它们一次只能执行一个动画,实际需求需要多个动画来组合才能达到效果,Android为属性动画也提供了属性动画合集AnimatorSet。补间动画的组合通过AnimationSet实现,详见《补间动画:Tween Animation》。
1、AnimatorSet简介
AnimatorSet继承自Animator,在包android.animation中。AnimatorSet按指定顺序播放一组对象:可以将动画设置为一起播放,按顺序播放或在指定的延迟后播放。
在许多情况下,您想播放取决于另一个动画何时开始或结束的动画。Android系统可让您将动画捆绑在一起AnimatorSet,从而可以指定是同时,顺序还是在指定的延迟后开始动画。您还可以AnimatorSet在彼此之间嵌套对象。
2、组合动画
多个属性动画组合可以一起播放,或者顺序播放。AnimatorSet还可以嵌套AnimatorSet组合动画,总之灵活性、自由度比较高,开发者需要发挥自己的创意实现各种复杂的动画效果。这也要求对动画理解比较深,可以将复杂的动画简化拆分成若干个简单的动画组合。
2.1、playTogether
有两个重载的方法,都是传入一组Animator属性动画,这组动画一起执行。
①playTogether(Animator... items)
②playTogether(Collection<Animator> items)
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(mImageView, "scaleX", 1f, 1.6f);
objectAnimatorX.setEvaluator(new FloatEvaluator());
ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(mImageView, "scaleY", 1f, 1.6f);
objectAnimatorY.setEvaluator(new FloatEvaluator());
animatorSet.setInterpolator(new LinearInterpolator());
animatorSet.setDuration(1500);
animatorSet.playTogether(objectAnimatorX, objectAnimatorY);

X、Y放缩同时执行
2.2、playSequentially
同样有两个重载的方法,传入一组Animator属性动画,然后按顺序执行这些动画。
①playSequentially(Animator... items)
②playSequentially(List<Animator> items)
animatorSet.playSequentially(objectAnimatorX, objectAnimatorY);

先执行X,在执行Y方向放缩
3、AnimatorSet.Builder
AnimatorSet只提供了两种固定的方法,要么一起播放动画,要么顺序依次播放动画。好在AnimatorSet类中还提供了AnimatorSet.Builder类,让开发者可以自由的组合属性动画。
3.1、构造AnimatorSet.Builder
AnimatorSet.Builder的构造函数是包访问权限,开发者无法直接通过构造函数构造AnimatorSet.Builder实例
/**
* package-private constructor. Builders are only constructed by AnimatorSet, when the
* play() method is called.
*
* @param anim The animation that is the dependency for the other animations passed into
* the other methods of this Builder object.
*/
Builder(Animator anim) {
mDependencyDirty = true;
mCurrentNode = getNodeForAnimation(anim);
}
通过AnimatorSet的play()方法返回值获取AnimatorSet.Builder实例
AnimatorSet.Builder builder = animatorSet.play(objectAnimator);
3.2、with(Animator anim)
动画一起执行
//X、Y动画一起执行
AnimatorSet.Builder builder = animatorSet.play(objectAnimatorX);
builder.with(objectAnimatorY);

3.3、before(Animator anim)
在anim动画执行前先执行AnimatorSet集合中已有的动画
//先执行X,在执行Y动画
AnimatorSet.Builder builder = animatorSet.play(objectAnimatorX);
builder.before(objectAnimatorY);

3.4、after(Animator anim)
AnimatorSet中的动画在anim执行完之后在执行
//AnimatorSet中的动画objectAnimatorX在执行完objectAnimatorY后再执行
AnimatorSet.Builder builder = animatorSet.play(objectAnimatorX);
builder.after(objectAnimatorY);

3.5、after(long delay)
设置delay时间之后再播放AnimatorSet中的动画。
//1000ms之后再执行objectAnimatorX动画
AnimatorSet.Builder builder = animatorSet.play(objectAnimatorX);
builder.after(1000);

4、AnimatorSet监听器
AnimatorSet继承自Animator,当然也可以设置AnimatorListener监听器。关于属性动画监听器详见《属性动画:ValueAnimator及其监听器》。
animatorSet.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) {
}
});
一下实现4个接口,比较麻烦 ,大多数时候只需要关注其中某一个方法的回调。可以重写抽象类AnimatorListenerAdapter中的某个方法,比如只关注AnimatorSet动画的开始,那么只需要重写onAnimationStart()方法即可
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
}
});
5、其它方法
了解一下AnimatorSet中的其它方法。
5.1、动画状态
①pause():暂停正在播放的动画。 仅在启动动画的同一线程上调用此方法。
②end():必须在运行动画的线程上调用此方法。
③resume():恢复已暂停的动画,使动画师在暂停时从中断处开始拾取。 仅在启动动画的同一线程上调用此方法。
④reverse():反向播放AnimatorSet。注意:无限AnimatorSet不支持反向。
⑤boolean isRunning():如果此AnimatorSet的任何子动画已开始但尚未结束,则返回true。
⑥boolean isStarted():返回此Animator是否已启动但尚未结束,不可重复使用的Animator在启动后始终返回true,因为它们无法返回到未启动状态。
5.2、get方法
①ArrayList<Animator> getChildAnimations():返回由此AnimatorSet控制的子Animator对象的当前列表。 这是内部列表的副本; 对返回列表的修改不会影响AnimatorSet,尽管对基础Animator对象的更改将影响由AnimatorSet管理的那些对象。
②long getCurrentPlayTime():返回自动画开始以来经过的毫秒数。
③long getDuration():获取此AnimatorSet的每个子动画的长度。 该值可能小于0,这表示尚未在此AnimatorSet上设置持续时间,并且每个子动画将使用其自己的持续时间。
④TimeInterpolator getInterpolator():返回此动画使用的时间插值器。
⑤long getStartDelay():调用start()后延迟动画启动的时间(以毫秒为单位)。
⑥long getTotalDuration():获取动画的总持续时间,说明动画序列,开始延迟和重复。 如果持续时间是无限的,则返回DURATION_INFINITE。
5.3、set方法
①setCurrentPlayTime(long playTime):将动画的位置设置为指定的时间点。
②setDuration(long duration):设置此AnimatorSet当前每个子动画的长度。 默认情况下,每个子动画将使用其自己的持续时间。 如果在AnimatorSet上设置了持续时间,则每个子动画都会继承此持续时间。
③setInterpolator(TimeInterpolator interpolator):设置此AnimatorSet的所有当前子动画的TimeInterpolator。 默认值为null。
④setTarget(Object target):设置此AnimatorSet的所有当前子动画的目标对象。
⑤setupStartValues():此方法告诉对象使用适当的信息来提取动画的起始值。 例如,一个AnimatorSet对象会将此调用传递给其子对象,以告诉他们设置值。 ObjectAnimator对象将使用其有关其目标对象和PropertyValuesHolder对象的信息来获取其属性的起始值。 ValueAnimator对象将忽略该请求,因为它没有足够的信息(例如目标对象)来收集这些值。
⑥setupEndValues():此方法告诉对象使用适当的信息来提取动画的结束值。 例如,一个AnimatorSet对象会将此调用传递给其子对象,以告诉他们设置值。 ObjectAnimator对象将使用其有关其目标对象和PropertyValuesHolder对象的信息来获取其属性的起始值。 ValueAnimator对象将忽略该请求,因为它没有足够的信息(例如目标对象)来收集这些值。
相关博客:
Android Developers > Docs > Reference > AnimatorSet
Choreograph multiple animations using an AnimatorSet
android.animation- AnimatorSet
Android源码分析--动画框架AnimatorSet
Android动画-属性动画-AnimatorSet