Android 动画之集合动画AnimatorSet

相关文章
Android 动画之视图动画
Android 动画之插值器
Android 动画之属性动画ValueAnimator
Android 动画之属性动画ObjectAnimator
Android 动画之集合动画AnimatorSet
Android 动画之布局动画
视图动画(View Animation)和属性动画(Property Animation)他们分别继承于Animation和Animator两种不同的抽象类。所以从根本上也将他们做了不同类型的区分。View Animation有个AnimationSet,Property Animation有个AnimatorSet,所以在代码上区分View Animation和Property Animation时,我们只要看他们的结尾处是animation还是animator就可以判断它是视图动画还是属性动画。本文主要介绍AnimatorSet的使用,set就是集合的意思,AnimatorSet就是将多个属性动画集合在一起使用。下面来看代码具体的实现吧。

这里写图片描述

XML中的用法

文件保存路径

res/animator/filename.xml

语法:

<set
  android:ordering=["together" | "sequentially"]>

    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <set>
        ...
    </set>
</set>

例子:

res/animator/setanimator.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:ordering="sequentially">

    <objectAnimator
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="alpha"
        android:duration="3000"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="1"/>

    <objectAnimator
        android:interpolator="@android:anim/anticipate_overshoot_interpolator"
        android:propertyName="scaleX"
        android:duration="3000"
        android:valueType="floatType"
        android:valueFrom="0.5"
        android:valueTo="1.5"
        ></objectAnimator>

</set>

代码中的应用

AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(SetActivity.this, R.animator.setanimator);
animatorSet.setTarget(textView);
animatorSet.start();

从代码中可以看出AnimationSet和ObjectAnimator的使用差不多,只是AnimatorSet可以将多个属性动画集合起来使用。


代码中动态创建

AnimatorSet提供了4中方法用于集合动画的创建。

playSequentially(Animator... items)
playSequentially(List<Animator> items)
playTogether(Animator... items)
playTogether(Collection<Animator> items)

这里它主要有两种操作类型,Sequentially和Together,通过它们的英文意思,我们可以知道就是系列和一起的意思,放在这个方法里面来理解的话就是依次播放还是同时播放。目前,这还只是我们的猜测,我们在代码中实际操作验证一下。

ObjectAnimator animatorA = ObjectAnimator.ofFloat(textView, "TranslationX", -300, 300, 0);
ObjectAnimator animatorB = ObjectAnimator.ofFloat(textView, "scaleY", 0.5f, 1.5f, 1f);
ObjectAnimator animatorC = ObjectAnimator.ofFloat(textView, "rotation", 0, 270, 90, 180, 0);

AnimatorSet animatorSet2 = new AnimatorSet();
animatorSet2.playTogether(animatorA, animatorB, animatorC);
animatorSet2.setDuration(3*1000);
animatorSet2.start();

上面实现的效果就是animatorA、animatorB、animatorC同时开始执行。如果是playSequentially的话就是animatorA、animatorB、animatorC依次执行,就不上代码了。接下来我们看下AnimatorSet提供的Build类。

public class Builder {
        private Node mCurrentNode;

        Builder(Animator anim) {
            mCurrentNode = mNodeMap.get(anim);
            if (mCurrentNode == null) {
                mCurrentNode = new Node(anim);
                mNodeMap.put(anim, mCurrentNode);
                mNodes.add(mCurrentNode);
            }
        }

        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 dependency = new Dependency(mCurrentNode, Dependency.WITH);
            node.addDependency(dependency);
            return this;
        }

        public Builder before(Animator anim) {
            Node node = mNodeMap.get(anim);
            if (node == null) {
                node = new Node(anim);
                mNodeMap.put(anim, node);
                mNodes.add(node);
            }
            Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER);
            node.addDependency(dependency);
            return this;
        }

        public Builder after(Animator anim) {
            Node node = mNodeMap.get(anim);
            if (node == null) {
                node = new Node(anim);
                mNodeMap.put(anim, node);
                mNodes.add(node);
            }
            Dependency dependency = new Dependency(node, Dependency.AFTER);
            mCurrentNode.addDependency(dependency);
            return this;
        }

        public Builder after(long delay) {
            // setup dummy ValueAnimator just to run the clock
            ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
            anim.setDuration(delay);
            after(anim);
            return this;
        }
    }

通过查看Build的代码,可以知道它的构造函数不是public的,所以我们只能通过AnimatorSet的play方法来获得Buidler对象。Builder提供了before、after、with等方法,我们来看下代码中的实际应用。

ObjectAnimator animatorA = ObjectAnimator.ofFloat(textView, "TranslationX", -300, 300, 0);
ObjectAnimator animatorB = ObjectAnimator.ofFloat(textView, "scaleY", 0.5f, 1.5f, 1f);
ObjectAnimator animatorC = ObjectAnimator.ofFloat(textView, "rotation", 0, 270, 90, 180, 0);

AnimatorSet animatorSet3 = new AnimatorSet();
animatorSet3.play(animatorA).after(animatorC).before(animatorB);
animatorSet3.setDuration(3*1000);
animatorSet3.start();

实现的效果就是先播放animatorC的动画,再播放animatorA的动画,最后在播放animatorB的动画。
其实,我们通过查看playSequentially和playTogether的源码知道,它们的实现也是通过调用Build类实现的,下面给出playTogether的源码。

public void playTogether(Animator... items) {
    if (items != null) {
        mNeedsSort = true;
        Builder builder = play(items[0]);
        for (int i = 1; i < items.length; ++i) {
            builder.with(items[i]);
        }
    }
}

通过上面的代码知道playTogether的实现就是通过调用了builder.with()实现了动画的同时播放。AnimatorSet的介绍就差不多讲完了,感兴趣的同学一定要多动手去敲敲代码,加深理解。

源代码

参考文章

Animation Resources
自定义控件三部曲之动画篇(九)——联合动画的代码实现
自定义控件三部曲之动画篇(十)——联合动画的XML实现与使用示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值