文章目录
- 一.前言
- 二.补间动画的缺陷
- 三.属性动画的优势
- 四.三种常见的属性动画类
- 1.ValueAnimator
- 2.ObjectAnimator
- 3.AnimatorSet
- 五.Animator监听器
- 六.使用XML编写动画
- 七.属性动画的高级使用及工作原理
一.前言
自Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation),它的功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。
关于 逐帧动画,补间动画可以参看这篇博客
Android 动画深入分析(一)——逐帧动画,补间动画
二.补间动画的缺陷
- 补间动画是只能够作用在View上的
使用补间我们其它任何继承自View的组件进行动画操作,但是如果我们想要对一个非View的对象进行动画操作,补间动画就帮不上忙了。 - 它只能够实现移动、缩放、旋转和淡入淡出这四种动画操作,基本上没有任何扩展性可言。
- 它只是改变了View的显示效果而已,而不会真正去改变View的属性。
三.属性动画的优势
- 它对作用对象进行了扩充,属性动画可以对任何对象做动画,甚至可以没有对象。不再是仅仅针对于View。
- 效果得到加强,不仅仅支持补件动画的四种简单变换,它可以对任意属性做动画。
- 它是真正去改变View的属性。
四.三种常见的属性动画类
- ValueAnimator
- ObjectAnimator
- 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帮助我们完成的。
注意:
- ofFloat()方法当中是可以传入任意多个参数的,比如
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);
anim.setDuration(5000);
anim.start();
表示将一个值在5秒内从0过渡到5,再过渡到3,再过渡到10。
- ofInt()方法,与上面的区别就是传入的是整数,且过渡的中间值也是整数
ValueAnimator anim = ValueAnimator.ofInt(0, 100);
3.ValueAnimator的作用:只是对值进行了一个平滑的动画过渡
2.ObjectAnimator
ObjectAnimator继承自ValueAnimator,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的translate(平移),scale(缩放),rotate(旋转),alpha(渐变)属性。
使用:
- 让textView在5秒内右移1000像素又回到原处
ObjectAnimator animator1 = ObjectAnimator.ofFloat(textView,"translationX",0,1000F,0);
animator1.setDuration(5000);
animator1.start();
- 改变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:///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 动画深入分析(三)——属性动画的高级使用及工作原理