Android动画机制总结笔记--属性动画PropertyAnimation篇之AnimatorSet

注意:本篇文章是本人阅读关于Android动画的文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于

  1. Android高级进阶 顾浩鑫
  2. 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();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342