注意:本篇文章是本人阅读关于Android动画的文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。
本篇文章内容来自于
- Android高级进阶 顾浩鑫
- Android自定义控件三部曲文章索引之动画篇
目录
--4.3 AnimatorSet 组合动画
----4.3.1 同时开始动画 playTogether
----4.3.2 逐个开始动画 playSequentially
----4.3.3 自由决定动画开始的顺序 AnimatorSet.Builder
------4.3.3.1 获取AnimatorSet.Builder实例
------4.3.3.2 AnimatorSet.Builder的设置动画顺序的函数
------4.3.3.3 AnimatorSet.Builder使用方式2种
------4.3.3.4 AnimatorSet.Builder实现代码
----4.3.4 AnimatorSet监听器
----4.3.5 AnimatorSet的函数
----4.3.6 AnimatorSet XML实现
4.3 AnimatorSet
用来组合多个Animator(ValueAnimator/ObjectAnimator),并指定这些Animator的播放顺序。
4.3.1 同时开始动画 playTogether
playTogether表示所有动画一起开始。
public void playTogether(Animator... items);
public void playTogether(Collection<Animator> items);
注意
playTogether和playSequentially在开始动画时,只是把每个控件的动画激活,至于每个控件自身的动画是否具有延时setRepeatCount、是否无限循环setRepeatCount,只与控件自身的动画设定有关,与playTogether、playSequentially无关。
即如果想要实现永久动画,需要在控件自身动画Animator设置setRepeatCount,AnimatorSet没有setRepeatCount这个方法。
playTogether代码实现
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(tvAnimPropertyShow1, "translationY", 0, 200, -300, 300);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(tvAnimPropertyShow2, "translationX", 0, 100, 200, 100);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(objectAnimator1, objectAnimator2);
animatorSet.setDuration(3000);
animatorSet.start();
4.3.2 逐个开始动画 playSequentially
playSequentially表示所有动画依次播放。
public void playSequentially(Animator... items);
public void playSequentially(List<Animator> items);
注意:playSequentially只负责到点激活动画,动画是否重复是否延迟与动画Animator本身设置有关。
playSequentially只有上一个控件做完动画以后,才会激活下一个控件的动画,如果上一控件的动画是无限循环,那下一个控件就别再指望能做动画了。
playSequentially代码实现
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(tvAnimPropertyShow1, "translationY", 0, 200, -300, 300);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(tvAnimPropertyShow2, "translationX", 0, 100, 200, 100);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(objectAnimator1, objectAnimator2);
animatorSet.setDuration(3000);
animatorSet.start();
4.3.3 自由决定动画开始的顺序 AnimatorSet.Builder
可以利用AnimatorSet.Builder自由的组合动画,
比如我们有三个动画A,B,C我们想先播放C然后同时播放A和B。playTogether和playSequentially无法实现。
4.3.3.1 获取AnimatorSet.Builder实例
//调用AnimatorSet中的play方法是获取AnimatorSet.Builder对象的唯一途径
//表示要播放哪个动画
public Builder play(Animator anim)
4.3.3.2 AnimatorSet.Builder的设置动画顺序的函数
//和前面动画一起执行
public Builder with(Animator anim)
//执行前面的动画后才执行该动画
//当play(playAnim)与before(beforeAnim)共用,则表示在播放beforeAnim之前,先播放playAnim动画;
public Builder before(Animator anim)
//执行先执行这个动画再执行前面动画
//当play(playAnim)与after(afterAnim)共用时,则表示在在播放afterAnim动画之后,再播放playAnim动画。
public Builder after(Animator anim)
//延迟n毫秒之后执行动画
public Builder after(long delay)
play(Animator anim)表示当前在播放哪个动画,另外的with(Animator anim)、before(Animator anim)、after(Animator anim)都是以play中的当前所播放的动画为基准的
4.3.3.3 AnimatorSet.Builder使用方式2种
方式一:使用builder对象逐个添加动画
AnimatorSet.Builder builder = animatorSet.play(tv1TranslateY);
builder.with(tv2TranslateY);
builder.after(tv1BgAnimator);
方式二:串行方式
由于每个函数的返回值都是Builder对象,所以我们是依然可以直接调用Builder的所有函数的,所以就可以用串行的方式把他们一行串起来,所以上面的代码我们也可以写成下面的简化方式:
animatorSet.play(tv1TranslateY).with(tv2TranslateY).after(tv1BgAnimator);
4.3.3.4 AnimatorSet.Builder实现代码
代码一:AnimatorSet.Builder实现2个动画一起做
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(tvAnimPropertyShow1, "translationY", 0, 200, -300, 300);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(tvAnimPropertyShow2, "translationX", 0, 100, 200, 100);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(3000);
AnimatorSet.Builder builder = animatorSet.play(objectAnimator1);
builder.with(objectAnimator2);
animatorSet.start();
代码二:在tv1颜色变化后,两个控件一同开始位移动画:
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(tvAnimPropertyShow1, "translationY", 0, 200, -300, 300);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(tvAnimPropertyShow2, "translationX", 0, 100, 200, 100);
ObjectAnimator objectAnimator3 = ObjectAnimator.ofInt(tvAnimPropertyShow1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
AnimatorSet animatorSet = new AnimatorSet();
AnimatorSet.Builder builder = animatorSet.play(objectAnimator3);
builder.before(objectAnimator1);
builder.before(objectAnimator2);
animatorSet.setDuration(3000);
animatorSet.start();
4.3.4 AnimatorSet监听器
和ValueAnimator/ObjectAnimator的监听器一样 因为都是Animator的子类
监听器接口:
public static interface AnimatorListener {
//当AnimatorSet开始时调用
void onAnimationStart(Animator animation);
//当AnimatorSet结束时调用
void onAnimationEnd(Animator animation);
//当AnimatorSet被取消时调用
void onAnimationCancel(Animator animation);
//当AnimatorSet重复时调用,由于AnimatorSet没有设置repeat的函数,所以这个方法永远不会被调用
void onAnimationRepeat(Animator animation);
}
添加方法为:
public void addListener(AnimatorListener listener);
注意
1、AnimatorSet的监听函数也只是用来监听AnimatorSet的状态的,与其中的动画的变化无关,只有当AnimatorSet的状态发生变化时,才会被调用;
2、AnimatorSet中没有设置循环的函数,所以AnimatorSet监听器中永远无法运行到onAnimationRepeat()中!
4.3.5 AnimatorSet的函数
//设置单次动画时长
public AnimatorSet setDuration(long duration);
//设置加速器
public void setInterpolator(TimeInterpolator interpolator)
//设置ObjectAnimator动画目标控件
public void setTarget(Object target)
在AnimatorSet中设置以后,会覆盖单个ObjectAnimator中的设置;
即如果AnimatorSet中没有设置,那么就以ObjectAnimator中的设置为准。
如果AnimatorSet中设置以后,ObjectAnimator中的设置就会无效。
比如:
只要通过AnimatorSet的setTartget函数设置了目标控件,那么AnimatorSet中的每个动画中的目标控件都为setTarget设置的控件。
//设置延时开始动画时长
public void setStartDelay(long startDelay)
当AnimatorSet所拥有的函数与单个动画所拥有的函数冲突时,就以AnimatorSet设置为准。但唯一的例外就是setStartDelay。
setStartDelay函数不会覆盖单个动画的延时,而且仅针对性的延长AnimatorSet的激活时间,单个动画的所设置的setStartDelay仍对单个动画起作用。
4.3.6 AnimatorSet XML实现
标签<set />对应AnimatorSet
4.3.6.1 标签字段意义及使用方法
<set
android:ordering=["together" | "sequentially"]>
4.3.6.2 代码实现
4.3.6.2.1 res/animator新建animator_set.xml文件
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueFrom="0"
android:valueTo="400"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueFrom="0"
android:valueTo="300"
android:valueType="floatType"/>
</set>
4.3.6.2.1 加载动画
AnimatorSet animator = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animtor_set);
animator.setTarget(tvAnimPropertyShow1);
animator.start();