上一篇总结了View动画相关的知识,这一节主要学习Android种的属性动画–也是当前最经常使用的一种动画。它能实现View动画所不能实现的一些动画效果。

1.简介

属性动画(Property Animation)是在 Android 3.0(API 11)后才提供的一种全新动画模式,它大大解决传统动画的局限性,如:经过动画后,其点击事件的响应区域依然未改变。它具有相当高的灵活性,我们可以通过反射机制动态的设置某一个类种的属性从而达到动画的效果。

作用对象:任意Java对象

具体逻辑:此图引用自感谢作者
\"在这里插入图片描述\"

其继承结构:
\"在这里插入图片描述\"

而我们平常主要使用的是ValueAnimator Animator,下面主要介绍它的使用。

2.TypeEvaluator-估值器

如果想要自定义复杂的动画效果,那么我们必须要了解TypeEvaluator。什么是TypeEvaluator呢?
简单来说,就是告诉动画系统如何从初始值过度到结束值。ValueAnimator内部自带FloatEvaluator。我们通过源码可以发现其实现了·TypeEvaluator接口,并且重写了evaluate方法

/**
 * This evaluator can be used to perform type interpolation between <code>float</code> values.
 */
public class FloatEvaluator implements TypeEvaluator<Number> {

    /**
     * This function returns the result of linearly interpolating the start and end values, with
     * <code>fraction</code> representing the proportion between the start and end values. The
     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
     * and <code>t</code> is <code>fraction</code>.
     *
     * @param fraction   The fraction from the starting to the ending values
     * @param startValue The start value; should be of type <code>float</code> or
     *                   <code>Float</code>
     * @param endValue   The end value; should be of type <code>float</code> or <code>Float</code>
     * @return A linear interpolation between the start and end values, given the
     *         <code>fraction</code> parameter.
     */
    public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
}
变量 含义
fraction 表示动画完成度
startValue 表示动画开始值
endValue 表示动画结束值

3.ValueAnimator的基本使用

看一个简单的Demo,学习基本的使用:

  //ValueAnimator
        //0-2-1之间在5s内重复执行2次,延时一秒开始执行
        //final ValueAnimator animator = ValueAnimator.ofFloat(0f,2f,1f);
        final ValueAnimator animator = ValueAnimator.ofInt(0, 2, 1);
        //动画持续时长
        animator.setDuration(5000);
        //重复次数
        animator.setRepeatCount(2);
        //延迟多久后开始执行
        animator.setStartDelay(1000);
        //动画重复模式,RESTART代表重新播放  REVERSE代表倒序播放
        animator.setRepeatMode(ValueAnimator.RESTART);
        //进度更新的监听
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.e(\"wdl\", \"onAnimationUpdate: \" + (int) animation.getAnimatedValue());
            }
        });

基本的方法有:
\"在这里插入图片描述\"

3. Animator的基本使用

Animator.ofXxx( target,String propertyName,Args...value),第一个参数代表目标对象,第二个参数为想要操作的属性名,最后一个为一个可变长参数。

 //独立动画效果
        //透明度
        final  Animator alpha Animator =  Animator
                .ofFloat(imageView,\"alpha\",1f,0f,1f);
        //旋转
        final  Animator rotate Animator =  Animator
                .ofFloat(imageView,\"rotation\",0f,360f);
        //缩放
        final  Animator scaleX Animator =  Animator
                .ofFloat(imageView,\"scaleX\",1f,2f,1f);
        final  Animator scaleY Animator =  Animator
                .ofFloat(imageView,\"scaleY\",1f,2f,1f);
        float translateY = imageView.getTranslationY();
        Log.e(\"wdl\", \"translateY: \"+translateY);
        final  Animator translateY Animator =  Animator.
                ofFloat(imageView,\"translationY\",
                translateY,-600f,translateY);

//        alpha Animator.setDuration(5000);
//        rotate Animator.setDuration(5000);
//        scaleX Animator.setDuration(5000);
//        scaleY Animator.setDuration(5000);
//        translateY Animator.setDuration(5000);

        //FloatEvaluator
        //组合动画
        final AnimatorSet animatorSet = new AnimatorSet();
        //play方法返回一个Builder对象
        //树结构
        //after 就是在当前的基础上添加一个父亲节点 ,只能添加一个父亲节点(子节点只能有一个父亲节点)
        //before 在当前基础上添加孩子节点,可以添加2个子节点
        animatorSet.play(translateY Animator).with(alpha Animator)
                .after(rotate Animator)
                .before(scaleX Animator).before(scaleY Animator);
        animatorSet.setDuration(5000);
        //添加所有的监听
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimati (Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        //根据需求重写监听方法
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }

            @Override
            public void onAnimati (Animator animation) {
                super.onAnimati (animation);
            }
        });

其中AnimatorSet,组合动画有四个方法:

//play方法返回一个Builder对象
        //树结构
        //after 就是在当前的基础上添加一个父亲节点 ,只能添加一个父亲节点(子节点只能有一个父亲节点)
        //before 在当前基础上添加孩子节点,可以添加2个子节点
        animatorSet.play(translateY Animator).with(alpha Animator)
                .after(rotate Animator)
                .before(scaleX Animator).before(scaleY Animator);
        animatorSet.setDuration(5000);

查看相关源码:

 /**
         * Sets up the given animation to play when the animation supplied in the
         * {@  AnimatorSet#play(Animator)} call that created this <code>Builder</code>  
         * ends.
         *
         * @param anim The animation that will play when the animation supplied to the
         * {@  AnimatorSet#play(Animator)} method ends.
         */
        public Builder before(Animator anim) {
            Node node = getNodeForAnimation(anim);
            mCurrentNode.addChild(node);
            return this;
        }

        /**
         * Sets up the given animation to play when the animation supplied in the
         * {@  AnimatorSet#play(Animator)} call that created this <code>Builder</code>  
         * to start when the animation supplied in this method call ends.
         *
         * @param anim The animation whose end will cause the animation supplied to the
         * {@  AnimatorSet#play(Animator)} method to play.
         */
        public Builder after(Animator anim) {
            Node node = getNodeForAnimation(anim);
            mCurrentNode.addParent(node);
            return this;
        }

可以看出,使用的是树结构:

方法 作用
play 方法返回一个Builder对象
with 与play种的动画一起执行
after 就是在当前的基础上添加一个父亲节点 ,只能添加一个父亲节点(子节点只能有一个父亲节点),此动画在前面的动画之前执行
before 在当前基础上添加孩子节点,可以添加2个子节点,在前面的动画之后执行

4.总结一下常用的方法

方法 作用
setDuration 动画持续时长
setRepeatCount 动画重复次数
setStartDelay 动画延时开始的时长
setRepeatMode 动画重复模式
addUpdateListener 动画监听

5. 中使用

动画相关文件位于res/animator/下。

基本使用:(基本的属性作用与Java代码中的类似)

<?  version=\"1.0\" encoding=\"utf-8\"?>
<set  ns:android=\"http://schemas.android.com/apk/res/android\"
    android:ordering=\"sequentially\">
    <!--   android:ordering    sequentially按照 文件中的先后顺序执行    together同时执行 -->
    < Animator
        android:duration=\"2000\"
        android:propertyName=\"translationX\"
        android:valueFrom=\"-500\"
        android:valueTo=\"0\"
        android:valueType=\"floatType\" />

    <set android:ordering=\"together\">
        < Animator
            android:duration=\"3000\"
            android:propertyName=\"rotation\"
            android:valueFrom=\"0\"
            android:valueTo=\"360\"
            android:valueType=\"floatType\" />
        <set android:ordering=\"sequentially\">
            < Animator
                android:duration=\"1500\"
                android:propertyName=\"alpha\"
                android:valueFrom=\"1\"
                android:valueTo=\"0\"
                android:valueType=\"floatType\" />
            < Animator
                android:duration=\"1500\"
                android:propertyName=\"alpha\"
                android:valueFrom=\"0\"
                android:valueTo=\"1\"
                android:valueType=\"floatType\" />
        </set>
    </set>
</set>

Java中使用:

 Animator  Animator = AnimatorInflater.loadAnimator(this,R.animator.animations);
 //将动画设置给对应的view
 Animator.setTarget(imageView);
 Animator.start();

本文参考:
https://blog.csdn.net/guolin_blog/article/details/43816093
https://www.jianshu.com/p/2412d00a0ce4

收藏 打印