Android 三种动画详解
背景
Andorid系统提供了很多丰富的API 去实现2D 和 3D的动画,最主要的划分可以分为如下几类:
- View Animation:视图动画在古老的andoid 版本系统中就已经提供了,只能被用来设置View的动画
- Drawabe Animation :这种动画(也叫Frame动画、帧动画)其实可以划分到视图动画的类别,专门用来一个一个的显示Drawable 的
resources,就像幻灯片一样。 - Property Animation :属性动画只对Android3.0 (API 11)以上的版本的Android系统才有效,这种动画可以设置给任何Object,包括那些还没有渲染到屏幕上的对象
可以看到当前应用程序开发涉及的主要动画也就这三大类。
2、View Animation (视图动画)使用详情
2.1 视图动画概述
视图动画,也叫Tween(补间)动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。例如,如果你有一个TextView对象,你可以移动,旋转,缩放,透明度设置其文本,当然,如果它有一个背景图像,背景图像会随着文本变化。
补间动画通过XML 或 Android 代码定义,建议使用XML 文件定义,因为它更具可读性,可重用性。
2.2 视图动画详细说明
Animation 抽象类是所有补间动画类的基类,所以基类会提供一些通用的动画属性方法。
2.2.1 Animation属性详解
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.2.2 Alpha(透明度) 属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromAlpha | AlphaAnimation(float fromAlpha,…) | 动画开始的透明度(0.0到1.0,0.0全透明,1.0不透明) |
android:toAlpha | AlphaAnimation(…,float toAlpha) | 动画结束的透明度,同上 |
2.2.3 Rotate(旋转) 属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromDegrees | RotateAnimation(float fromDegress, …) | 旋转开始角度,正代表顺时针度数,负代表逆时针度数 |
android:toDegress | RotateAnimation(…,float toDegress) | 旋转结束角度,正代表顺时针度数,负代表逆时针度数 |
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.2.4: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宽度的50%作为起始点,50%p表示以当前view的左上角加上父控件宽高的50%作为起始点) |
android:pivotY | ScaleAnimation(…,float pivotY) | 缩放起点Y轴坐标,同上规律 |
2.2.5:Translate (翻译,转换)属性详解
xml属性 | java方法 | 解释 |
---|---|---|
android:fromXDelta | TranslateAnimation(float fromXDelta, …) | 起始点X坐标(数值,百分数,百分数p,比如:50表示以当前view左上角坐标加上50px为起始点、50%表示以当前View左上角坐标加上当前View宽高的50%作为起始点、50%p表示以当前View的左上角坐标加上父容器的宽高的50%作为初始点) |
android:fromYDelta | TranslateAnimation(…,float fromYDelta,…) | 初始化Y轴坐标,同上规律 |
android:toXDelta | TranslateAnimation(…,float toXDelta,…) | 结束点X轴坐标,同上规律 |
android:toYDelta | TranslateAnimation(…,float toYDelta) | 结束点Y轴坐标,同上规律 |
2.2.6:AnimationSet详解
AnimationSet继承自 Animation ,是上面四种的组合容器管理类,没有自己特殊的属性,它的属性继承自Animation,所以特别注意,当我们对set标签使用Animation的属性时会对该标签下的所有子控件都产生影响
2.3 视图动画使用方法
通过上面对于动画的属性介绍之后我们来看看如何使用(用XML方式)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>
加载xml动画
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
上面就是一个标准的使用我们定义的补间动画的模板,至于补间动画的使用,Animation 还有如下一些比较使用的方法:
Animation类的方法 | 解释 |
---|---|
reset() | 重置Animation的初始化 |
cancel() | 取消Animation动画 |
start() | 开始Animation动画 |
setAnimationListener(AnimationLisntenr listener) | 给当前Animation动画设置动画监听 |
hasStarted() | 判断当前Animation是否开始 |
hasEnded() | 判断当前Animation是否结束 |
View中与动画相关的方法:
View类的常用动画操作方法 | 解释 |
---|---|
startAnimation(Animation animation) | 设置当前View的animation动画 |
clearAnimation() | 取消当前View在执行的animation动画 |
2.4 视图动画注意事项
特别特别注意 : 补间动画执行后并没有改变View的真实布局属性值。切记这一点,譬如我们在Activity 中有一个Button在屏幕上方,我们设置了平移动画移动到屏幕的下方,然后保持动画最后执行状态待在屏幕下方,这是如果点击屏幕下方动画执行之后的按钮是没有任何反应的,而点击原来屏幕上方没有Button的地方却响应的是点击Button的事件
2.5 插值器简介
各类插值器都是实现了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_interpoltor | 类似上面的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 | 新增,定义路径坐标后按照路径坐标来跑 |
如上就是系统提供的一些插值器。
2.5.2 :插值器的使用方法
插值器的使用比较简单,如下
<set
android:interpolator="@android:anim/accelerate_interpolator" //插值器
android:sharedinterpolator="true"> //set标签内所有动画共享插值器
...
</set>
2.5.3:插值器的自定义
有时候你会发现系统提供的插值器不够用,可能就像View一样自定义。关于插值器的自定义分为两种实现方法,xml自定义实现(其实就是对现有的插值器的一些属性的改变),或者java代码实现方法。
看看XML自定义插值器的步骤:
- 在res/anim/目录下创建filename.xml文件
- 修改你准备自定义的插值器如下:
3.在你的补间动画文件中引用该文件即可<?xml version="1.0" encoding="utf-8" ?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
3 、Drawable Animation(Drawable动画)使用详解
3.1 Drawable 动画概述
Drawable 动画其实就是Frame动画(帧动画),它允许你实现向幻灯片一样的效果,这种动画的实质是Drawable,所以这种动画的XML定义方式文件一般放在 res/drawable/ 目录下
3.2 Drawable 动画详细说明
我们依旧可以使用XML 或者 java 实现帧动画,但是依旧推荐使用xml,具体如下:
<animation-list 必须是根节点,包含一个或者多个 <item 元素,属性有:
- android:oneshot true 代表只执行一次,false 循环执行
- <item 类似一帧的动画资源
<item animation-list的子项,包含属性如下:
- android:drawable 一个frame的Drawable资源
- android:duration 一个frame显示多长时间
3.3 Drawable 动画实例
关于帧动画相对来说比较简单,这里给出一个常规使用框架,如下:
<!-- 注意:rocket.xml文件位于res/drawable/目录下 -->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource_name"
android:duration="integer" />
</animation-list>
帧动画xml的使用:
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
特别注意:AnimationDrawable 的start() 方法不能在Activity的onCreate方法中调用,因为AnimationDrawable还未完全附着在window上,所以最好的调用时机是onWindowFocusChanged() 方法中
4、Property Animation(属性动画)使用详解
在使用属性动画之前先看几个常用的View属性成员
- translationX, translationY :控制View的位置,值是相对于View容器左上角坐标的偏移
- rotationX, rotationY:控制相对于轴心旋转
- x, y:控制View在容器中的位置,即左上角坐标加上translationX, translationY 的值
- alpha:控制View对象的alpha透明度值
4.1 :动画属性描述
Android 3.0 以后引进动画属性描述,属性动画可以轻而易举的实现许多View动画做不到的事,譬如 3D旋转一张图片。
java类名 | xml 关键字 | 描述信息 |
---|---|---|
ValueAnimator | <animator 放置在res/animator/目录下 | 在一个特定的时间里执行一个动画 |
TimeAnimator | 不支持 | 时序监听回调工具 |
ObjectAnimator | <objectAnimator 放置在res/animator/目录下 | 一个对象的一个属性动画 |
AnimatorSet | <set 放置在res/animator/目录下 | 动画集合 |
4.2 :属性动画详细说明