Android 动画种类
View Animation: 视图动画(Tween(补间)动画),只能被用来设置View的动画。
Drawable Animation: 帧动画(也叫 Frame 动画)其实可以划分到视图动画的类别,专门用来一个一个的显示 Drawable 的resources,就像放幻灯片一样。
Property Animation: 属性动画只对 Android 3.0(API 11)以上版本的Android 系统才有效,这种动画可以设置给任何 Object,包括那些还没有渲染到屏幕上的对象。这种动画是可扩展的,可以让你自定义任何类型和属性的动画。
1. View Animation 视图动画使用解析
-
-
视图动画特点
- 视图动画可以在一个视图容器内执行一系列简单变换(平移、缩放、旋转、透明度)
- 视图动画通过XML 或 Android 代码定义,建议使用 XML 文件定义,因为它更具可读性、可重用性。
-
-
- 动画属性
xml属性 | java 方法 | 解释 |
---|---|---|
android:detachWallpaper | setDetachWallpaper(boolean) | 是否在壁纸上运行 |
android:duration | setDuration(long) | 动画持续时间,毫秒为单位 |
android:fillAfter | setFillAfter(boolean) | 控件动画结束时是否保持动画最后的状态 |
android:fillBefore | setFillBefore(boolean) | 控件动画结束时是否还原到开始动画前的状态 |
android:fillEnabled | setFillEnabled(boolean) | 与android:fillBefore效果相同 |
android:interpolator | setInterpolator(Interpolator) | 设定插值器(指定的动画效果,譬如回弹等) |
android:repeatCount | setRepeatCount(int) | 重复次数 |
android:repeatMode | setRepeatMode(int) | 重复类型有两个值,reverse表示倒序回放,restart表示从头播放 |
android:startOffset | setStartOffset(long) | 调用start函数之后等待开始运行的时间,单位为毫秒 |
android:zAdjustment | setZAdjustment(int) | 表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal |
2-1 Alpha属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromAlpha | AlphaAnimation(float fromAlpha, …) | 动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明) |
android:toAlpha | AlphaAnimation(…, float toAlpha) | 动画结束的透明度,同上 |
2-2 Rotate属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromDegrees | RotateAnimation(float fromDegrees, …) | 旋转开始角度,正代表顺时针度数,负代表逆时针度数 |
android:toDegrees | RotateAnimation(…, float toDegrees, …) | 旋转结束角度,正代表顺时针度数,负代表逆时针度数 |
android:pivotX | RotateAnimation(…, float pivotX, …) | 缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点) |
android:pivotY | RotateAnimation(…, float pivotY) | 缩放起点Y坐标,同上规律 |
2-3 Scale属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromXScale | ScaleAnimation(float fromX, …) | 初始X轴缩放比例,1.0表示无变化 |
android:toXScale | ScaleAnimation(…, float toX, …) | 结束X轴缩放比例 |
android:fromYScale | ScaleAnimation(…, float fromY, …) | 初始Y轴缩放比例 |
android:toYScale | ScaleAnimation(…, float toY, …) | 结束Y轴缩放比例 |
android:pivotX | ScaleAnimation(…, float pivotX, …) | 缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点) |
android:pivotY | ScaleAnimation(…, float pivotY) | 缩放起点Y轴坐标,同上规律 |
2-4 Translate属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromXDelta | TranslateAnimation(float fromXDelta, …) | 起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点) |
android:toXDelta | TranslateAnimation(…, float toXDelta, …) | 结束点X轴坐标,同上规律 |
android:fromYDelta | TranslateAnimation(…, float fromYDelta, …) | 起始点Y轴从标,同上规律 |
android:toYDelta | TranslateAnimation(…, float toYDelta) | 结束点Y轴坐标,同上规律 |
2-5 AnimationSet详解
AnimationSet 继承自 Animation,是上面四种的组合容器管理类,没有自己特有的属性,他的属性也继承自 Animation 。所以特别注意,当我们对set标签使用 Animation 的属性时会对该标签下的所有子控件都产生影响。
2-6 View Animation 使用实例
- xml 使用实例
在 R.anim 目录下新建一个动画 xml文件。
在 java代码中使用:
ImageView image= (ImageView) findViewById(R.id.image);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
image.startAnimation(animation);
2-7 Animation 比较实用的方法介绍:
Animation类的方法 | 解释 |
---|---|
reset() | 重置Animation的初始化 |
cancel() | 取消Animation动画 |
start() | 开始Animation动画 |
setAnimationListener(AnimationListener listener) | 给当前Animation设置动画监听 |
hasStarted() | 判断当前Animation是否开始 |
hasEnded() | 判断当前Animation是否结束 |
2-8 View 中和视图动画相关的几个常用方法:
View类的常用动画操作方法 | 解释 |
---|---|
startAnimation(Animation animation) | 对当前 View 开始设置的Animation 动画 |
clearAnimation() | 取消当前 View 在执行的 Animation 动画 |
2-9 视图动画需要注意的地方
- 视图动画执行完之后并未改变 View 的真实布局属性值。
切记这一点,譬如我们在 Activity 中有一个 Button 在屏幕上方,我们设置了平移动画移动到屏幕下方,然后保持动画最后执行状态,看起来 Button
是在屏幕下方,但是这时点击屏幕下方动画执行之后的 Button,Button 是没有任何反应的,而点击原来屏幕上方原来是 Button 的地方却能响应点击Button的事件。这可以说是视图动画的一个 bug 。
2-10 视图动画插值器 Interpolator
- Android 的各种插值器都实现了Interpolator接口,系统提供的插值器具体如下:
java类 | xml id值 | 描述 |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 动画始末速率较慢,中间加速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 动画开始速率较慢,之后慢慢加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 开始的时候从后向前甩 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 类似上面AnticipateInterpolator |
BounceInterpolator | @android:anim/bounce_interpolator | 动画结束时弹起 |
CycleInterpolator | @android:anim/cycle_interpolator | 循环播放速率改变为正弦曲线 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 动画开始快然后慢 |
LinearInterpolator | @android:anim/linear_interpolator | 动画匀速改变 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 向前弹出一定值之后回到原来位置 |
PathInterpolator | 新增,定义路径坐标后按照路径坐标来跑。 |
- 插值器使用方法:
在 res/anim/ 目录下创建 my_Interpolator.xml 插值器文件。r如下:
在视图动画文件中引用自定义的或者系统提供的。
2. Drawable Animation(Drawable动画)使用详解
Drawable 动画其实就是 Frame 动画(帧动画),它允许你实现像播放幻灯片一样的效果,这种动画的实质其实是 Drawable,所以这种动画的XML 定义方式文件一般放在 res/drawable/ 目录下。
-
Drawable动画详细说明
我们依旧可以使用 xml 或者 java 方式实现帧动画。但是依旧推荐使用xml,具体如下:
必须是根节点,包含一个或者多个 - 元素,属性有:
android:oneshot true 代表只执行一次,false 循环执行。
- 类似一帧的动画资源。
- animation-list 的子项,包含属性如下:
android:drawable:一个 frame 的 Drawable 资源。
android:duration :一个 frame 显示多长时间。 - 元素,属性有:
举个栗子:
在 java 代码中调用:
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
PS 注意的地方:
AnimationDrawable.start()
方法不能在 Activity 的 onCreate
方法中调运,因为 AnimationDrawable 还未完全附着到 window 上,所以最好的调运时机是 onWindowFocusChanged()
方法中。
3. Property Animation(属性动画)使用详解
上文说了视图动画最大的缺陷就是改变的只是显示,并不能显示响应事件。因此,Android 在 3.0 后推出 Property Animation
(属性动画)来解决这个问题。
在属性动画中,使用的最多情况就是:AnimatorSet 和 ObjectAnimator 搭配。使用一个 ObjectAnimator 可以控制对象的一个属性,而使用多个 ObjectAnimator 就可以控制对象的多个属性,组合到 AnimatorSet 就组成了动画。
属性动画很重要的一点就是:属性动画通过调用属性的 get
、set
方法来真实控制一个View的属性值,因此可以响应事件。
3-1 ObjectAnimator
-
ObjectAnimator
是属性动画框架中最重要的实行类。创建一个ObjectAnimator
对象通过它的静态方法就可以了。
举个栗子
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationX",300);
animator.setDuration(3000);
animator.start();
该静态方法的第一个参数是要操纵的View,第二个是要操纵的属性,第三个是一个可变的数组参数,也可以是一个值,一个值表示变化到此值。
-
ObjectAnimator
要操纵的属性必须具有get
、set
方法,不然ObjectAnimator
不会生效,常见的可以操纵的属性如下:
translationX 和 translationY:这两个属性作为一种增量来控制着 View 对象从它布局容器的左上角坐标偏移的位置。
rotation、rotationX 和 rotationY:这三个属性控制 View 对象围绕支点进行 2D 和 3D 旋转。
scaleX、scaleY:控制 View 对象围绕它的支点进行 2D 缩放。
pivotX、pivotY:控制 View 对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,支点就是该 View 的中心点。
x、y:这两个属性是 View 对象在它的容器中的最终位置,是最初的左上角的 translationX、translationY 值得累计和。
alpha:View 的透明度。1 为不透明,0 为全透明。
3-2 PropertyValuesHolder
类似视图动画的 AnimationSet
,在属性动画中,如果针对同一个对象的多个属性,要同时作用多种动画,可以使用 PropertyValuesHolder
来实现。
举个栗子
//平移的同时改变X,Y轴的缩放
PropertyValuesHolder pv1 = PropertyValuesHolder.ofFloat("translationX",300f);
PropertyValuesHolder pv2 = PropertyValuesHolder.ofFloat("scaleX",1f,0,1f);
PropertyValuesHolder pv3 = PropertyValuesHolder.ofFloat("scaleY",1f,0,1f);
ObjectAnimator.ofPropertyValuesHolder(imageView,pv1,pv2,pv3).setDuration(3000).start();
3-3 ValueAnimatior
ValueAnimatior
本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字,从而让调用者控制动画的实现过程。
举个栗子
ValueAnimator animator = ValueAnimator.ofInt(0,1000);
animator.setTarget(imageView);
animator.setDuration(3000).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer)animation.getAnimatedValue();
//使用这个 value 改变 View 的状态
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = value;
imageView.setLayoutParams(layoutParams);
}
});
3-4 AnimationSet
AnimationSet
能对同一个对象的多个属性同时进行动画效果,还能实现精确的顺序控制,这点比 PropertyValuesHolder
更灵活。
举个栗子
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,"translationX",300);
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView,"translationY",300);
animatorSet.setDuration(3000);
animatorSet.play(animator).after(animator1);
animatorSet.start();
在属性动画中,AnimationSet
通过 playTogether()
(同时播放)、playSequentially()
(顺序播放)、animatorSet.play().with()
(同时播放)、animatorSet.play().before()
(先 play()
后 before()
)、animatorSet.play().after()
(先 after()
后 play()
)这些方法来控制多个动画的协同工作方式,从而控制动画的播放顺序。
3-4 属性动画的事件监听
一个完整的动画具有 Start
、Repeat
、End
、Cancel
四个过程,我们可以很方便地监听其中一个或者几个事件。
举个栗子
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,"translationX",300);
animator.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) {
}
});
或者监听其中一个事件:
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,"translationX",300);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
3-5 在XML中使用属性动画
属性动画和视图动画一样,可以直接写在 XML 中,通过 AnimatorInflater.loadAnimator(context,res)
使用。
举个栗子
在 res 目录下新建一个 animator 目录(注意不能是 anim
),然后写 XML 文件。
在代码中引用:
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.object_animation);
animator.setTarget(imageView);
animator.start();
4. 总结
动画在安卓中使用的非常普遍,是当地使用动画能增添程序的趣味性。本篇介绍了安卓常见的动画的用法,下一篇介绍如何自定义动画。
参考资料
Android应用开发之所有动画使用详解