Android 动画深入分析(二)——属性动画的简单使用

一.前言

自Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation),它的功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。

关于 逐帧动画,补间动画可以参看这篇博客
Android 动画深入分析(一)——逐帧动画,补间动画

二.补间动画的缺陷

  1. 补间动画是只能够作用在View上的
    使用补间我们其它任何继承自View的组件进行动画操作,但是如果我们想要对一个非View的对象进行动画操作,补间动画就帮不上忙了。
  2. 它只能够实现移动、缩放、旋转和淡入淡出这四种动画操作,基本上没有任何扩展性可言。
  3. 它只是改变了View的显示效果而已,而不会真正去改变View的属性。

三.属性动画的优势

  1. 它对作用对象进行了扩充,属性动画可以对任何对象做动画,甚至可以没有对象。不再是仅仅针对于View。
  2. 效果得到加强,不仅仅支持补件动画的四种简单变换,它可以对任意属性做动画。
  3. 它是真正去改变View的属性。

四.三种常见的属性动画类

  1. ValueAnimator
  2. ObjectAnimator
  3. AnimatorSet

1.ValueAnimator

ValueAnimator是整个属性动画机制当中最核心的一个类,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外.,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。

使用:
比如说想要将一个值从0平滑过渡到1,时长300毫秒,就可以这样写:

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.start();

为了看到效果,我们给他添加上监听器并用log打印

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
//添加监听器
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    //这个方法可以拿到当前的值
        float currentValue = (float) animation.getAnimatedValue();
        Log.d("TAG", "cuurent value is " + currentValue);
    }
});
anim.start();

打印结果:
在这里插入图片描述
可以看到值在300毫秒的时间内从0平滑过渡到了1,这个计算工作就是由ValueAnimator帮助我们完成的。
 
注意:

  1. ofFloat()方法当中是可以传入任意多个参数的,比如
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);
anim.setDuration(5000);
anim.start();

表示将一个值在5秒内从0过渡到5,再过渡到3,再过渡到10。
 

  1. ofInt()方法,与上面的区别就是传入的是整数,且过渡的中间值也是整数
ValueAnimator anim = ValueAnimator.ofInt(0, 100);

3.ValueAnimator的作用:只是对值进行了一个平滑的动画过渡

2.ObjectAnimator

ObjectAnimator继承自ValueAnimator,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的translate(平移),scale(缩放),rotate(旋转),alpha(渐变)属性。
 
使用:

  1. 让textView在5秒内右移1000像素又回到原处
ObjectAnimator animator1 =  ObjectAnimator.ofFloat(textView,"translationX",0,1000F,0);
        animator1.setDuration(5000);
        animator1.start();
  1. 改变VIew的背景色,实现由红到蓝的无限变换
        ValueAnimator animator2 = ObjectAnimator.ofInt(textView,"backgroundColor",
                0xFFFF8080,0xFF8080FF);
        animator2.setDuration(3000);        //设置持续时间
        animator2.setEvaluator(new ArgbEvaluator());
        animator2.setRepeatCount(ValueAnimator.INFINITE);       //设置动画循环播放的次数,这里是无限循环
        //设置循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思
        animator2.setRepeatMode(ValueAnimator.REVERSE);

3.AnimatorSet

借助AnimatorSet这个类我们可以实现组合动画功能,实现组合大致有如下两种方法:

  • play()方法
    如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
方法名 说明
after(Animator anim) 将现有动画插入到传入的动画之后执行
after(long delay) 将现有动画延迟指定毫秒后执行
before(Animator anim) 将现有动画插入到传入的动画之前执行
with(Animator anim) 将现有动画和传入的动画同时执行

使用:
如下让让TextView在5秒内先从屏幕外移动进屏幕,然后开始旋转360度,旋转的同时进行淡入淡出操作,就可以这样写:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
  • playTogether方法
    这个方法只能让所有的动画一起执行,相等于上面的with

使用:
5秒内对View的旋转,平移,缩放,和透明度进行改变

AnimatorSet set = new AnimatorSet();
        set.playTogether(
                ObjectAnimator.ofFloat(textView,"rotationX",0,360,0),     //在水平方向进行旋转
                ObjectAnimator.ofFloat(textView,"rotationY",0,180,0),     //在垂直方向进行旋转

                ObjectAnimator.ofFloat(textView,"rotation",0,-90,0),      //旋转

                ObjectAnimator.ofFloat(textView,"translationX",0,90,0),   //在水平方向平移
                ObjectAnimator.ofFloat(textView,"translationY",0,90,0),   //在垂直方向平移

                ObjectAnimator.ofFloat(textView,"scaleX",1,1.5f,1),       //在水平方向上进行缩放
                ObjectAnimator.ofFloat(textView,"scaleY",0,0.5f,1),       //在垂直方向上进行缩放

                ObjectAnimator.ofFloat(textView,"alpha",1,0.25f,1)      //透明度
        );
        set.setDuration(5 * 1000).start();

五.Animator监听器

Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。

anim.addListener(new AnimatorListener() {
	@Override
	public void onAnimationStart(Animator animation) {
	
	}
 
	@Override
	public void onAnimationRepeat(Animator animation) {
	//动画重复执行的时候调用
	}
 
	@Override
	public void onAnimationEnd(Animator animation) {
	}
 
	@Override
	public void onAnimationCancel(Animator animation) {
	//动画被取消的时候调用
	}
});

此外,Android提供了一个适配器类,叫作AnimatorListenerAdapter,它继承自AnimatorListener(),使用这个类可以解决掉实现接口繁琐的问题,可以只监听一个方法。

anim.addListener(new AnimatorListenerAdapter() {
	@Override
	public void onAnimationEnd(Animator animation) {
	}
});

六.使用XML编写动画

 
通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松,比如某个将通用的动画编写到XML里面,我们就可以在各个界面当中轻松去重用它。
 
如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:

  • 对应代码中的ValueAnimator
  • 对应代码中的ObjectAnimator
  • 对应代码中的AnimatorSet

使用xml实现上面的组合动画:
 
1.新建res/amimator/anim1

<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" >
    </objectAnimator>

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

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

</set>

 2.使用

Animator animator = AnimatorInflater.loadAnimator(MainActivity.this,R.animator.anim1);
animator.setTarget(textView);
animator.start();

对于xml文件中的一些标签说明

标签 说明
android:propertyName 属性动画的作用对象的属性的名称
android:duration 动画的时长
android:valueFrom 动画的起始值
android:valueTo 动画的结束值
android:startOffset 动画的延迟时间
android:repeatCount 动画的重复次数
android:repeatMode 动画的重复模式,包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思
android:valueType 表示 android:propertyName所指属性的类型,如果android:propertyName所指向的是颜色,不需要指定 android:valueType

七.属性动画的高级使用及工作原理

Android 动画深入分析(三)——属性动画的高级使用及工作原理

猜你喜欢

转载自blog.csdn.net/haazzz/article/details/114701850