先上代码:
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(textView1, "translationY", 0, 200, 0);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(textView2, "translationY", 0, 200, 0);
objectAnimator1.setStartDelay(2000);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(objectAnimator1).with(objectAnimator2);
animatorSet.setStartDelay(2000);
animatorSet.setDuration(2000);
animatorSet.start();
简单的两个TextView控件位移动画,放在一个AnimatorSet中调用play,with一起执行,第一个动画setStartDelay(2000);第二个动画没有设置开始延迟,然后在设置AnimatorSet.setStartDelay(2000);调用start开始,实际运行结果和预想的不太一样,预想结果是动画开始后先延迟2秒然后第二动画执行2秒后第一个动画才开始执行,实际运行结果为延迟4s后,两个TextView控件同时进行位移动画后结束。
这里调用animatorSet.play(objectAnimator1).with(objectAnimator2);和调用animatorSet.playTogether本质上一样,因为通过看源码playTogether也是通过play和with方法实现的。
playTogether方法实现:
public void playTogether(Animator... items) {
if (items != null) {
Builder builder = play(items[0]);
for (int i = 1; i < items.length; ++i) {
builder.with(items[i]);
}
}
}
因为结果与预想不同,于是来看一下源码到底为什么会出现这个效果。
看play方法:
public Builder play(Animator anim) {
if (anim != null) {
mNeedsSort = true;
return new Builder(anim);
}
return null;
}
play方法中直接返回一个Builder对象。接着看Builder的构造函数:
Builder(Animator anim) {
mCurrentNode = mNodeMap.get(anim);
if (mCurrentNode == null) {
mCurrentNode = new Node(anim);
mNodeMap.put(anim, mCurrentNode);
mNodes.add(mCurrentNode);
}
}
AnimatorSet中的mNodeMap和mNodes用来存放所有节点,mNodeMap的key是animator,value是node。将传入的动画封装成一个Node加入集合中:
/**
* Contains all nodes, mapped to their respective Animators. When new
* dependency information is added for an Animator, we want to add it
* to a single node representing that Animator, not create a new Node
* if one already exists.
*/
private HashMap<Animator, Node> mNodeMap = new HashMap<Animator, Node>();
/**
* Set of all nodes created for this AnimatorSet. This list is used upon
* starting the set, and the nodes are placed in sorted order into the
* sortedNodes collection.
*/
private ArrayList<Node> mNodes = new ArrayList<Node>();
Builder中mCurrentNode表示当前动画的节点:
/**
* This tracks the current node being processed. It is supplied to the play() method
* of AnimatorSet and passed into the constructor of Builder.
*/
private Node mCurrentNode;
接下来看with方法:
public Builder with(Animator anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
mNodeMap.put(anim, node);
mNodes.add(node);
}
Dependency dependen