1.Android动画的分类
- 帧动画(Frame Animation):一系列的图片在同一个位置进行连贯的替换操作
- 补间动画(Tween Animation):专门用于View,可以实现透明度、缩放、旋转和平移四种效果。
- 属性动画(Property Animation):表面上效果和补间动画差不多。
补间动画和属性动画之间最大的差异:
补间动画只能作用于View,并且只能简单的去进行透明度、缩放、旋转和平移这四种动画,其他的比如去更改颜色,字体大小粗细等就无能为力了。但是属性动画,可以设置在任何对象上,并且可以去改变对象的属性。
2.属性动画准许定义的参数
- 持续时间,默认为300ms。
- 时间差值
- 重复次数和行为
- 动画集合(多个动画组合在一起)
- 帧刷新延迟,默认10ms;但最终靠系统的整体繁忙程度和底层定时器服务的速度。
3.ObjectAnimator
ObjectAnimator是最常用的一个,其使用相对简单,只要设置几个参数,一个属性动画就实现了。
常用API
返回值类型 |
方法名 |
功能 |
ObjectAnimator |
clone() |
返回一个该对象的副本 |
String |
getPropertyName() |
获取被动画化的属性名称 |
Object |
getTarget() |
被动画化的对象 |
static ObjectAnimator |
ofArgb(……) |
改变颜色值 |
static ObjectAnimator |
ofFloat(……) |
在浮点数值之间进行动画化 |
static ObjectAnimator |
ofInt(……) |
在int值之间进行动画化 |
static ObjectAnimator |
ofMultiFloat(……) |
多个参数设置器的浮点值进行动画化 |
static ObjectAnimator |
ofObject(……) |
在对象之间动画化 |
void |
setAutoCancel(boolean cancel) |
当启动具有相同目标和属性的任何其他ObjectAnimator时,autoCancel会控制是否自动取消ObjectAnimator。 |
ObjectAnimator |
setDuration(long duration) |
设置动画持续时间 |
void |
setTarget(Object object) |
设置要动画化的对象 |
void |
start() |
开始动画 |
还用一些set方法,是把of系列的方法的参数拆开来设置了。详情可以去查看ObjectAnimator的API
例:执行单个动画
1 2 3 4 5 6 7 8 9 10
| ObjectAnimator.ofFloat(btStart,"translationY",0f,500f) .setDuration(3000) .start();
objectAnimator = new ObjectAnimator(); objectAnimator.setFloatValues(10f,23f,43f,15f,55f); objectAnimator.setTarget(btStart); objectAnimator.setPropertyName("translationY"); objectAnimator.setDuration(5000); objectAnimator.start();
|
4.组合动画
同时运行动画
- 多个动画同时运行
方式一:
1 2 3
| ObjectAnimator.ofFloat(image, "translationX", 0f, 500f).setDuration(3000).start(); ObjectAnimator.ofFloat(image, "translationY", 0f, 500f).setDuration(3000).start(); ObjectAnimator.ofFloat(image, "rotation", 0f, 360f).setDuration(3000).start();
|
方式二:
1 2 3 4 5 6
| PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", 0f, 500f); PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("translationY", 0f, 500f); PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f); ObjectAnimator.ofPropertyValuesHolder(image, holder1, holder2, holder3) .setDuration(3000) .start();
|
方式三:
1 2 3 4 5 6 7
| ObjectAnimator animator1 = ObjectAnimator.ofFloat(image, "translationX", 0f, 500f); ObjectAnimator animator2 = ObjectAnimator.ofFloat(image, "translationY", 0f, 500f); ObjectAnimator animator3 = ObjectAnimator.ofFloat(image, "rotation", 0f, 360f); AnimatorSet set = new AnimatorSet(); set.setDuration(3000); set.playTogether(animator1, animator2, animator3); set.start();
|
- 多个动画按一定顺序运行
方式一:使用AnimatorSet实现
1 2 3 4 5 6 7 8
| ObjectAnimator animator1 = ObjectAnimator.ofFloat(image, "translationX", 0f, 500f); ObjectAnimator animator2 = ObjectAnimator.ofFloat(image, "translationY", 0f, 500f); ObjectAnimator animator3 = ObjectAnimator.ofFloat(image, "rotationX", 0f, 360f); ObjectAnimator animator4 = ObjectAnimator.ofFloat(image, "rotationY", 0f, 360f); AnimatorSet set = new AnimatorSet(); set.play(animator3).before(animator2).after(animator1).with(animator4); set.setDuration(3000); set.start();
|
方式二:使用动画监听事件AnimatorListener实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ObjectAnimator animator1 = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f); final ObjectAnimator animator2 = ObjectAnimator.ofFloat(image, "translationX", 0f, 500f); final ObjectAnimator animator3 = ObjectAnimator.ofFloat(image, "translationY", 0f, 500f); animator1.setDuration(3000); animator2.setDuration(3000); animator3.setDuration(3000);
animator1.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { animator2.start(); } @Override public void onAnimationEnd(Animator animation) { animator3.start(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animator1.start();
|
方法三:使用动画监听事件AnimatorListenerAdapter实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ObjectAnimator animator1 = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f); final ObjectAnimator animator2 = ObjectAnimator.ofFloat(image, "translationX", 0f, 500f); final ObjectAnimator animator3 = ObjectAnimator.ofFloat(image, "translationY", 0f, 500f); animator1.setDuration(3000); animator2.setDuration(3000); animator3.setDuration(3000);
animator1.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { animator3.start(); } @Override public void onAnimationStart(Animator animation) { animator2.start(); } }); animator1.start();
|
5.ValueAnimator
和ObjectAnimator使用方法基本相同,不同之处在于ValueAnimator不能指定运行动画的对象.从而必须设置一个动画监听器,通过不断监听当前动画运行到的属性值来动态的进行处理.
1 2 3 4 5 6 7 8 9 10
| ValueAnimator animator = ValueAnimator.ofInt(0, 100); animator.setDuration(2000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); ((Button) view).setText(value + ""); } }); animator.start();
|
6.使用XMl编写动画
过去的补间动画可以通过XML的方式编写,属性动画也可以编写到XML文件中。编写到XML文件中的一个好处是可以方便的实现动画的重用。
我们需要在项目的res目录下创建一个名为animator的文件夹,在这个文件夹中定义动画。animator动画XML文件中可以包括以下三种标签:
<animator>
:相当于JAVA代码中的ValueAnimator;
<objectAnimator>
:相当于JAVA代码中的ObjectAnimator;
<set>
:相当于JAVA代码中的AnimatorSet。
7.TypeEvaluate
作用是告诉动画如何从初始值过渡到结束值。
ObjectAnimator.ofFloat()中默认的TypeEvaluate是其子类FloatEvaluate,其效果是使动画在初始值与结束值之间进行平滑的过度.
1 2 3 4 5 6
| public class FloatEvaluator implements TypeEvaluator<Number> { public Float evaluate(float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); } }
|
其实现方法evaluate的第一个参数为动画执行进度,相当于百分比,值在0~1之间;第二个参数为动画开始值;第三个参数是动画结束值.
TypeEvaluate使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| animator = ValueAnimator.ofObject(new TypeEvaluator() { @Override public Object evaluate(float fraction, Object startValue, Object endValue) { int start = Integer.parseInt((String) startValue); int end = Integer.parseInt((String) endValue); int result = (int) (start + fraction * (end - start)); return result + "%"; } }, "0", "100"); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { String value = (String) animation.getAnimatedValue(); btStart.setText(value); } }); animator.setDuration(6000); animator.start();
|
8.Interpolator
作用是控制动画的变化速率.
系统提供的有:
- BounceInterpolator:弹跳效果;
- AccelerateInterpolator:逐渐加速;
- DecelerateInterpolator:逐渐减速;
- AccelerateDecelerateInterpolator:先加速后减速;
- OvershootInterpolator:到达目标点时“跑过头了”,再返回到目标点;
- AnticipateInterpolator:移动之前先向后“助跑”;
- AnticipateOvershootInterpolator:OvershootInterpolator和AnticipateInterpolator的组合效果;
- CycleInterpolator:对于指定的动画,正向做一遍,反响做一遍;
我们也可以通过继承TimeInterpolator继承我们自己的插值器,或者是通过继承他的某些子类.TimeInterpolator接口中有一个抽象方法setInterpolation(),方法中有一个参数input,这个参数的值在整个动画过程中从0匀速变化到1,也就是相当于一个百分比,指示当前动画播放到哪了。
9.ViewPropertyAnimator
ViewPropertyAnimator是在Android 3.1的API中新加入的更加易懂、更加便于使用的动画API。
属性动画虽然可以对所有对象添加动画效果,但我们在使用过程中还是以对View使用动画为多,因此Google为我们提供了一个ViewPropertyAnimator,让我们可以简单的调用这套API来单独为View设置动画。
ViewPropertyAnimator让我们可以使用链式编程,一行代码为一个View对象设置属性,示例代码如下:
1 2 3 4 5 6
| textView.animate() .translationX(200) .translationY(200) .setDuration(2000) .setInterpolator(new BounceInterpolator()) .start();
|
当我们对一个View对象使用animate()方法时,就返回了一个ViewPropertyAnimator对象,这个对象中支持所有补间动画的API以及属性动画的API。ViewPropertyAnimator是默认执行的动画,也就是说,我们不需要在最后调用start()方法,动画也会自动播放。