Android动画之属性动画基础用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_435559203/article/details/53437129

在上一篇Android动画基础之补间动画与逐帧动画 ,我们复习了Android的基础动画Tweened Animation、Frame Animation,同时指出他们的缺陷,改变是View的显示效果而不是View本身的属性,还有我们不多不少会看多人家的APP有一些很酷炫的动画效果,但是我们Android本身的基础动画是用硬编码方式完成的,功能很有限,扩展性很差,无法满足的现今的产品需求。因为我们今次的主角要出现了,Property Animation属性动画。

属性动画(Property Animation) 属性动画是在Android3.0中引进的,它更改的是对象的实际属性,在基础动画中改变的是View的绘制效果,真正的View的属性是没有改变的,而属性动画,改变的是对象的实际属性,能编写各种满足我们需求的动画。

Property Animation相关类:

  • ValueAnimator:包括Property Animation动画的所有核心功能,如动画时间、开始、结束属性值。

  • ObjectAnimator:继承于ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为改该对象的相对属性。实际应用中一般会用ObjectAnimator来改变某一对象的某一属性。

  • AnimatorSet:提供了一个把多个动画组合成一个组合的机制。

  • AnimatorInflater:用于加载属性动画的xml文件

  • TypeEvalutors:类型估值,主要用于设置动画操作属性的值

Android提供了以下几个evalutor:

IntEvaluator:属性的值类型为int;
FloatEvaluator:属性的值类型为float;
ArgbEvaluator:属性的值类型为十六进制颜色值;

  • TimeInterplator:时间差值,定义了动画属性值变化的方式,在Property Animation中是TimeInterplator,在View Animation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了 TimeInterplator。Interplator继承自TimeInterplator,内部没有任何其他代码。

ValueAnimator

  • 调用ValueAnimator提供的静态方法实例化ValueAnimator对象,如ofArgb(int… values)、ofFloat(float… values)等,并设置目标属性的属性名、初始值、结束值等;
  • 调用ValueAnimator.addUpdateListener(AnimatorUpdateListener listener)为ValueAnimator对象设置属性变化的监听器;
  • 创建自定义的Interpolator,调用setInterpolator(TimeInterpolator value)为ValueAniamtor设置自定义的Interpolator;
  • 创建自定义的TypeEvaluator,调用setEvaluator(TypeEvaluator value)为ValueAnimator设置自定义的TypeEvaluator;
  • 在AnimatorUpdateListener中的实现方法为目标对象的属性设置计算好的属性值;
  • 设置动画的持续时间、是否重复及重复次数等属性;
  • 对ValueAnimator设置目标对象并开始执行动画。

下面我们简单地使用一下ValueAnimator:

                ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        Log.i("onAnimationUpdate", "onAnimationUpdate: " + animation.getAnimatedValue());
                    }
                });
                valueAnimator.setDuration(200);
                valueAnimator.start();

上面代码我们是用ofInt()方法,带的参数是0,100,然后通过用AnimatorUpdateListener设置动画监听,如下图看到动画的值在200毫秒内从0到100打印出来。

这里写图片描述

ObjectAnimator

我们接着学习一下ObjectAnimator这动画实现类的用法,首先ObjectAnimator继承ValueAnimator,那就说ObjectAnimator可以重写ValueAnimator父类提供的方法。在实际开发中,我们更多地使用ObjectAnimator来实现我们需要的动画效果。在之前我们说过ViewAnimation的缺点,所以Android3.0中为View增加了一些新属性以及对应的getter、setter方法。那我们来看一下这些新增的动画属性:

1.translationX和translationY:这两个属性控制着View的屏幕位置坐标变化量,以layout容器的左上角为坐标原点;
2.rotation、rotationX 和 rotationY:这三个属性控制着 2D 旋转角度(rotation属性)和围绕某枢轴点的 3D 旋转角度;
3.scaleX、scaleY:这两个属性控制着 View 围绕某枢轴点的 2D 缩放比例;
4.pivotX 和 pivotY: 这两个属性控制着枢轴点的位置,前述的旋转和缩放都是以此点为中心展开的,缺省的枢轴点是 View 对象的中心点;
5.x 和 y:这是指 View 在容器内的最终位置,等于 View 左上角相对于容器的坐标加上 translationX 和 translationY 后的值;
alpha:表示 View 的 alpha 透明度。缺省值为 1 (不透明),为 0 则表示完全透明(看不见);

然而用法跟ValueAnimator大同小异,我们通过例子来说明:

ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);  
animator.setDuration(1000);  
animator.start(); 

感觉是没区别啊,我们ObjectAnimator其实是对继承了View控件的属性setter、getter方法进行修改值的。ObjectAnimator可以在属性上进行操作,而ValueAnimator并没有在属性上做操作,ObjectAnimator对一些简单的动画使用起来比较方便,而ValueAnimator就比较灵活,之后我们会详细讲解。

组合动画AnimatorSet

组合动画,PropertyAnimation是用到AnimatorSet这个类,该类提供一个play()的方法,还有提供:

  • after(Animator anim) 将现有动画插入到传入的动画之后执行
  • after(long delay) 将现有动画延迟指定毫秒后执行
  • before(Animator anim) 将现有动画插入到传入的动画之前执行
  • with(Animator anim) 将现有动画和传入的动画同时执行
                ObjectAnimator moveIn = ObjectAnimator.ofFloat(image, "translationX", -100f, 0f);
                ObjectAnimator rotate = ObjectAnimator.ofFloat(image, "rotation", 0f, 180f);
                ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(image, "alpha", 1f, 0f, 1f);
                AnimatorSet animSet = new AnimatorSet();
                animSet.play(rotate).with(fadeInOut).after(moveIn);
                animSet.setDuration(2000);
                animSet.start();

感觉比较基础的用法。

XML编写动画

用XML来编写描述我们需要的动画可能是我们最常用的一种做法,所以PropertyAnimation肯定也提供这种XML的方式来实现功能。在XML我们常用到的三个标签:

  • <animator> 对应代码中的ValueAnimator
  • <objectAnimator> 对应代码中的ObjectAnimator
  • <set> 对应代码中的AnimatorSet

标签是可以嵌套的。
标签的android:ordering属性规定了这个set中的动画的执行顺序。该属性值默认是together (default)。

首先要在res目录下面新建一个animator文件夹,然后我们的XML代码的实现如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <objectAnimator
        android:duration="2000"
        android:propertyName="translationX"
        android:valueFrom="-500"
        android:valueTo="0"
        android:valueType="floatType" />

    <set android:ordering="together">
        <objectAnimator
            android:duration="3000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" />

        <set android:ordering="sequentially">
            <objectAnimator
                android:duration="1500"
                android:propertyName="alpha"
                android:valueFrom="1"
                android:valueTo="0"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="1500"
                android:propertyName="alpha"
                android:valueFrom="0"
                android:valueTo="1"
                android:valueType="floatType" />
        </set>
    </set>
</set>

XML文件写好,那么我们用Java代码将对于的动画加载并启动。

                Animator animator = AnimatorInflater.loadAnimator(this, R.animator.anim_set);
                animator.setTarget(image);
                animator.start();

Animator监听器

在动画的绘制中,肯定少不了我们的动画监听事件来处理各种需求和逻辑,Animator类当中提供了一个addListener()方法:

               mAnimator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {

                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });

可以看到,我们需要实现接口中的四个方法,onAnimationStart()方法会在动画开始的时候调用,onAnimationRepeat()方法会在动画重复执行的时候调用,onAnimationEnd()方法会在动画结束的时候调用,onAnimationCancel()方法会在动画被取消的时候调用。

但是有些时候我们可能只想要监听动画开始这一个事件,那么每次都要将四个接口全部实现一遍就显得非常繁琐。所以Android提供了一个适配器类,叫作AnimatorListenerAdapter,使用这个类就可以解决掉实现接口繁琐的问题了,如下所示:

                mAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        super.onAnimationStart(animation);
                    }
                });

好的,通过本篇文章的学习,我想大家已经对属性动画的基本API用法已经有了一定的认识,并把最常用的一些功能都掌握好了。接下来下一篇我们继续深入学习PropertyAnimation。

猜你喜欢

转载自blog.csdn.net/qq_435559203/article/details/53437129