动画第八步-> AnimatorSet:联合动画的代码实现

2016-12-21  本文已影响302人  crossroads
极客学院Animation教程讲解的很详细,点击进入哦

这里为学习的整理和补充O(∩_∩)O

一、概念大述

想必大家都看到赛马,在赛马开始前,每个马都会被放在起点的小门后面,到点了,门打开,马开始一起往前跑。

  • playSequentially 的意义就是当一匹马回来以后,再放另一匹。那如果上匹马永远没回来,那下一匹马也永远不会被放出来。
    放到动画上,就是把激活一个动画之后,动画之后的操作就是动画自己来负责了,这个动画结束之后,再激活下一个动画。如果上一个动画没有结束,那下一个动画就永远也不会被激活。

下面,我们就具体了解一下吧O(∩_∩)O~

二、基本用法

public void playSequentially(Animator... items);
public void playSequentially(List<Animator> items);
public void playTogether(Animator... items);
public void playTogether(List<Animator> items);

demo:(标注①②的地方此时忽略,在第三小节讲解)

//第一步,声明ObjectAnimator对象
colorOfView1 = ObjectAnimator.ofInt(view1, "backgroundColor", 0xffff00ff, 0xff00ff00);
translateOfView1 = ObjectAnimator.ofFloat(view1, "translationY", 0, -600);
//translateOfView1.setStartDelay(5000);③
translateOfView2 = ObjectAnimator.ofFloat(view2, "translationY", 0, 600);
rotateOfView2 = ObjectAnimator.ofFloat(view2, "rotation", 0, 300, 200);
//rotateOfView2.setStartDelay(2000);②
playSquentlyBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       playSquetially();
   }
});
playTogetherBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       playTogether();
   }
});
//依次播放,一个动画播放完毕后,才执行下一个
public void playSquetially() {
    animatorSetS = new AnimatorSet();
    animatorSetS.setDuration(3000);
    animatorSetS.playSequentially(translateOfView1, colorOfView1, translateOfView2, rotateOfView2);
    //animatorSetS.setStartDelay(1000);①
    animatorSetS.start();
}
//一起开始,所有动画同时执行start方法
public void playTogether() {
    animatorSetT = new AnimatorSet();
    animatorSetT.setDuration(3000);
    //animatorSetT.setTarget(view2);④
   animatorSetT.playTogether(translateOfView1, colorOfView1, translateOfView2, rotateOfView2);
   //animatorSetT.setStartDelay(1000);①
    animatorSetT.start();
}

执行效果:


playSequentially
playTogether

注意:
animatorSet.setDuration(3000)将3000这个值赋值给了每个ObjectAnimator对象的setDuration()方法,但是,在API15上AnimatorSet.setDuration()方法并没有给它的子objectAnimator设置解决方案是给每个add到animatorSet中的ObjectAnimator都设置自己的duration。(Android版本兼容问题)

三、延时这个坑~

1.将标注为①的代码注释去掉,执行 animatorSet.setStartDelay方法,该方法表示:门在1000ms之后打开,此时,马🐴开始往前跑。
2.此时,再将②标注的代码注释去掉,执行rotateOfView2.setStartDelay(2000),可以看到如下效果:
(门在1000ms之后打开,但是旋转动画这匹马等了2000ms才开始跑)


playSquentially.gif playTogether.gif

看到这里,可能有人要问了,坑呢?坑在哪里?这些很符合逻辑思维嘛,那接下来就一起踩坑吧Q_Q

playTogether.gif playSquentially.gif

表急,看下边⤵️:

 AnimatorSet 激活延时 = AnimatorSet.startDelay+第一个动画.startDelay

所以,1000ms+5000ms=6000ms之后,门被打开,然而由于translateOfView1这第一号马被用掉了延时,所以6000ms后直接开始,然而rotateOfView2没有被用掉延时,所以rotateOfView2需要再等2000ms才能执行

四、其他方法

  1. setTarget方法
//设置 ObjectAnimator 动画目标控件
public void setTarget(Object target)

将注释④去掉,就发现所有的动画都在view2上执行了,view1没有了任何的动作。

2.AnimatorSet.Builder方法【注意注意】

Builder对象通过play(Animator)建立
//和前面动画一起执行
 public Builder with(Animator anim)
 //在该动画之前执行前面的动画
 public Builder before(Animator anim)
 //在该动画之后执行前面的动画
 public Builder after(Animator anim)
 //在延迟 n 毫秒之后执行动画 
public Builder after(long delay)

demo:

animatorSet.play(anim1).with(anim2).after(anim3); 

//执行结果是anim3执行完毕后,anim1和anim2一起执行,表弄错了-

3.其他方法
在 AnimatorSet 中还有几个函数:

//设置单次动画时长
public AnimatorSet setDuration(long duration);
//设置加速器
public void setInterpolator(TimeInterpolator interpolator)
//设置 ObjectAnimator 动画目标控件
public void setTarget(Object target)

注意:在 AnimatorSet 中设置以后,会覆盖单个 ObjectAnimator 中的设置;即如果 AnimatorSet 中没有设置,那么就以 ObjectAnimator 中的设置为准。如果 AnimatorSet 中设置以后,ObjectAnimator 中的设置就会无效。

4.addListner添加监听

1、AnimatorSet 的监听函数也只是用来监听 AnimatorSet 的状态的,与其中的动画无关;
2、AnimatorSet 中没有设置循环的函数,即setRepeatCount(ValueAnimator.INFINITE),所以 AnimatorSet 监听器中永远无法运行到 onAnimationRepeat()中!

5.cancel()方法取消动画

参考文献

android 4.0.x上AnimatorSet.setDuration上的坑

上一篇下一篇

猜你喜欢

热点阅读