目录
一、帧动画(Frame Animation)
1、简介
就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。
2、实现
1)xml实现(在res/drawable下创建)
步骤一:创建帧动画文件
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<!--oneshot:是否只播放一次-->
<item
android:drawable="@drawable/picture"
android:duration="1000"/>
<item
android:drawable="@drawable/ic_launcher_background"
android:duration="1000"/>
</animation-list>
步骤二:将动画设置给控件
//方式一:设置成图片资源
imageView.setImageResource(R.drawable.frame_anim);
//方式二:设置成背景资源
//如果单纯想显示动画,需要把android:src去掉。否则图片会在动图上面
imageView.setBackgroundResource(R.drawable.frame_anim);
步骤三:获取AnimationDrawable对象(根据步骤二不同选择不同方式)
//方式一
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
//方式二
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
步骤四:开始动画
animationDrawable.start();
2)java实现
//1、创建AnimationDrawable对象
AnimationDrawable animationDrawable = new AnimationDrawable();
//2、设置是否播放一次
animationDrawable.setOneShot(false);
//3、添加帧图片
Drawable drawable1 = ContextCompat.getDrawable(this, R.drawable.picture);
Drawable drawable2 = ContextCompat.getDrawable(this, R.drawable.ic_launcher_background);
//添加帧图片,并设置持续时间
animationDrawable.addFrame(drawable1, 1000);
animationDrawable.addFrame(drawable2, 1000);
//4、将动画设置给控件
imageView.setImageDrawable(animationDrawable);
//或者
//imageView.setBackgroundDrawable(animationDrawable);
//5、开始动画
animationDrawable.start();
二、补间动画(Tween Animation)
1、简介
Tween Animation就是一系列View形状的变换,如大小的缩放、透明度的改变、水平位置的改变、旋转位置改变。动画的定义既可以用java代码定义也可以用XML定义。
2、分类
xml标签 | java对象 | 功能 |
---|---|---|
alpha | AlphaAnimation | 透明度动画 |
scale | ScaleAnimation | 缩放动画 |
rotate | RotateAnimation | 旋转动画 |
translate | TranslateAnimation | 平移动画 |
set | AnimationSet | 补间动画集合 |
3、属性
属性 | 功能 | 可适用动画 |
---|---|---|
android:interpolator | 动画运动的插值器 可以匀速、加速、减速或抛物线速度等各种速度变化 |
ALL |
android:duration | 持续的时间,单位为毫秒 | ALL |
android:repeatMode | 动画的重复方式。 可为reverse(反向)或restart(重新开始)(默认) |
ALL |
android:repeatCount | 动画的重复次数,播放次数=重复次数+1。 可以是infinite(无限循环) |
ALL |
android:fillEnabled | 是否使用fillBefore值,默认为true | ALL |
android:fillBefore | 动画完成后,保持动画前状态,默认true | ALL |
android:fillAfter | 动画完成后,保持动画后状态,默认false | ALL |
android:startOffset | 动画开始延迟时间 | ALL |
android:fromAlpha | 动画开始时的透明度。 0.0代表完全透明;1.0代表完全不透明 |
AlphaAnimation |
android:toAlpha | 动画结束时的透明度。 0.0代表完全透明;1.0代表完全不透明 |
AlphaAnimation |
android:fromXScale | 动画开始时x轴上的缩放系数 | ScaleAnimation |
android:toXScale | 动画结束时x轴上的缩放系数 | ScaleAnimation |
android:fromYScale | 动画开始时y轴上的缩放系数 | ScaleAnimation |
android:toYScale | 动画结束时y轴上的缩放系数 | ScaleAnimation |
android:pivotX | 缩放、旋转中心点x坐标 | ScaleAnimation RotateAnimation |
android:pivotY | 缩放、旋转中心点y坐标 | ScaleAnimation RotateAnimation |
android:fromDegrees | 动画开始时旋转的角度 | RotateAnimation |
android:toDegrees | 动画结束时旋转的角度 | RotateAnimation |
android:fromXDelta | 动画开始时x轴上的起始位置 | TranslateAnimation |
android:toXDelta | 动画结束时x轴上的起始位置 | TranslateAnimation |
android:fromYDelta | 动画开始时y轴上的起始位置 | TranslateAnimation |
android:toYDelta | 动画结束时y轴上的起始位置 | TranslateAnimation |
android:interpolotor的常用属性值
属性 | 描述 |
---|---|
@android:anim/linear_interpolator | 动画一直在做匀速改变 |
@android:anim/accelerate_interpolator | 在动画开始的地方改变速度较慢,然后开始加速 |
@android:anim/decelerate_interpolator | 在动画开始的地方改变速度较快,然后开始减速 |
@android:anim/accelerate_decelerate_interpolator | 动画在开始和结束的地方改变速度较慢,在中间的时候加速 |
@android:anim/cycle_interpolator | 动画循环播放特定的次数,速率改变沿着正弦曲线 |
@android:anim/bounce_interpolator | 动画结束的地方采用弹球效果 |
@android:anim/anticipate_interpolator | 在动画开始的地方先向后退一小步,再快速到达动画结束的地方 |
@android:anim/overshoot_interpolator | 动画快速到达终点,并超出一小步最后回到动画结束的地方 |
@android:anim/anticipate_overshoot_interpolator | 在动画开始的地方先向后退一小步,再开始动画,到结束的地方再超出一小步,最后回到动画结束的地方 |
pivotX等取值类型有三种:数字、百分比、百分比+”p”
数字:例如50.0,这里的单位是px像素
百分比:例如50%,这里是相对于自己控件的百分比
百分比+”p”:例如50%p,这里是表示相对于自己控件的父控件的百分比
4、透明度动画(AlphaAnimation)
1)xml实现(在res/anim下创建)
// 1、创建动画文件
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.2"
android:repeatCount="2">
</alpha>
//2、加载动画资源
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
//3、开启动画
imageView.startAnimation(animation);
2)java实现
//romAlpha:开始透明度。取值范围(全透明0.0f~不透明1.0f)
//toAlpha:结束透明度。 取值范围(全透明0.0f~不透明1.0f)
AlphaAnimation(float fromAlpha, float toAlpha)
//1、创建动画,并设置相关属性
AlphaAnimation animation = new AlphaAnimation(1.0f,0.2f);
animation.setDuration(500);
animation.setRepeatCount(2);
//2、开启动画
imageView.startAnimation(animation);
5、缩放动画(ScaleAnimation)
// fromX:开始缩放的X轴倍数。如1.0f:本身大小;如2.0f:从自己两倍开始
// toX:结束缩放的X轴倍数。
// fromY:开始缩放的Y轴倍数。
// toY:结束缩放的Y轴倍数。
// pivotXType:X轴缩放中心点类型;可选值有:
Animation.RELATIVE_TO_SELF相对自己--常用
Animation.RELATIVE_TO_PARENT相对父窗体
Animation.ABSOLUTE 绝对的---不常用
// pivotXValue:在pivotXType的基础上,X轴缩放中心的位置。如:0.5f:缩放中心就在控件的一半的位置。如果是0.0f,则会在控件本身的左边位置
// pivotYType:X轴缩放中心点类型;同上 ...
// pivotYValue:在pivotYType的基础上,Y轴缩放中心的位置。
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
6、旋转动画(RotateAnimation)
//fromDegrees:开始旋转的角度
//toDegrees:结束旋转的角度
//pivotXType:参照缩放动画
//pivotXValue:参照缩放动画
//pivotYType:参照缩放动画
//pivotYValue:参照缩放动画
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
7、平移动画(TranslateAnimation)
//fromXType:开始平移的X轴参照位置,一般使用Animation.RELATIVE_TO_SELF
//fromXValue:X轴平移的开始倍数。在fromXType的基础上。
//toXType:结束平移的X轴参照位置
//toXValue:X轴平移的结束倍数。
//fromYType:开始平移的Y轴参照位置
//fromYValue:Y轴平移的开始倍数。
//toYType:结束平移的Y轴参照位置
//toYValue:Y轴平移的结束倍数。
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)
8、动画合集(AnimationSet)
- xml实现(在res/anim下创建)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.2"
android:repeatCount="2"/>
<translate
android:fromXDelta="-30%p"
android:toXDelta="30%p"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="1000"
android:repeatCount="5"/>
</set>
- java实现
AnimationSet animationSet = new AnimationSet(true);
//将动画一个一个添加进来
animationSet.addAnimation(animation);
imageView.startAnimation(animationSet);
9、监听动画
animation.setAnimationListener(new Animation.AnimationListener() {
//动画开始时调用
@Override
public void onAnimationStart(Animation animation) {
}
//动画结束时调用
@Override
public void onAnimationEnd(Animation animation) {
}
//动画重复时调用
@Override
public void onAnimationRepeat(Animation animation) {
}
});
三、属性动画(Property Animation)
1、简介
自Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation).
属性动画的运行机制是通过不断地对值进行操作来实现的。
它的功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。
2、属性动画与补间动画的区别
最大的区别是补间动画就算控件移动到任何位置,控件本身位置还是不变。而属性动画是直接改变控件的位置。
3、ValueAnimator
ValueAnimator不提供任何动画效果,它更像一个数值发生器,用来产生有一定规律的数字,从而让调用者控制动画的实现过程。
//1、构建ValueAnimator的实例
//参数:一组动画变化过程的值
ValueAnimator animator = ValueAnimator.ofFloat(0, 180);
//2、设置相关属性
animator.setDuration(1000);
//3、设置动画的监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//4、利用添加的监听函数获取当前动画的值,getAnimatedValue()
float rotation = (Float) animation.getAnimatedValue();
//5、设置给View
//旋转180度
imageView.setRotation(rotation);
}
});
//6、开始动画
animator.start();
View方法 | 功能 |
---|---|
setX(float x) | x轴平移 |
setY(float y) | y轴平移 |
setRotation(float rotation) | 自身平面旋转 |
setRotationX(float rotationX) | 3D翻转 x轴不变 |
setRotationY(float rotationY) | 3D翻转 y轴不变 |
setAlpha(float alpha) | 透明度 |
setScaleX(float scaleX) | 横向缩放 |
setScaleY(float scaleY) | 纵向缩放 |
setTranslationX(float translationX) | x轴上移动(从自身开始) |
setTranslationY(float translationY) | y轴上移动(从自身开始) |
4、ObjectAnimator
ObjectAnimator是属性动画最重要的类,创建一个ObjectAnimator只需通过其静态工厂类直接返还一个ObjectAnimator对象。
//1、构建ObjectAnimator的实例
//ObjectAnimator.ofFloat(Object target, String propertyName, float... values)
//target:需要执行动画的组件
//propertyName:动画类型
//values:一组动画变化过程的值
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0, 180);
//2、设置相关属性
animator.setDuration(5000);
animator.setRepeatCount(3);
//3、开始动画
animator.start();
动画类型 | 功能 |
---|---|
X | x轴平移 |
Y | y轴平移 |
rotation | 自身平面旋转 |
rotationX | 3D翻转 x轴不变 |
rotationY | 3D翻转 y轴不变 |
alpha | 透明度 |
scaleX | 横向缩放 |
scaleY | 纵向缩放 |
translationX | x轴上移动(从自身开始) |
translationY | y轴上移动(从自身开始) |
5、组合动画
实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例。
AnimatorSet.Builder中包括以下四个方法:
- after(Animator anim):将现有动画插入到传入的动画之后执行。
- after(long delay):将现有动画延迟指定毫秒后执行。
- before(Animator anim):将现有动画插入到传入的动画之前执行。
- with(Animator anim):将现有动画和传入的动画同时执行。
ObjectAnimator translationX = ObjectAnimator.ofFloat(imageView, "translationX", 200);
ObjectAnimator rotation = ObjectAnimator.ofFloat(imageView, "rotation", 0, 360);
ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 1, 0, 1);
AnimatorSet animatorSet = new AnimatorSet();
//执行alpha后再同时执行translationX和rotation
//animatorSet.play(translationX).with(rotation).after(rotation);
//同时执行translationX、rotation、rotation
animatorSet.playTogether(translationX, rotation, alpha);
animatorSet.setDuration(5000);
animatorSet.start();
6、Animator监听器
objectAnimator.addListener(new Animator.AnimatorListener() {
/**
* 动画开始前的操作
* @param animation
*/
@Override
public void onAnimationStart(Animator animation) {
}
/**
* 动画结束的操作
* @param animation
*/
@Override
public void onAnimationEnd(Animator animation) {
}
/**
* 动画取消的操作
* @param animation
*/
@Override
public void onAnimationCancel(Animator animation) {
}
/**
* 动画重复的操作
* @param animation
*/
@Override
public void onAnimationRepeat(Animator animation) {
}
});
如果只关心动画的结束状态:
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
7、PropertyValuesHolder
还可以使用PropertyValuesHolder类来实现组合动画。不过这个组合动画就没有上面的丰富了,使用PropertyValuesHolder类只能是多个动画一起执行。
PropertyValuesHolder pv1 = PropertyValuesHolder.ofFloat("rotation", 0, 359);
PropertyValuesHolder pv2 = PropertyValuesHolder.ofFloat("scaleX", 1, 2);
PropertyValuesHolder pv3 = PropertyValuesHolder.ofFloat("translationX", 0, 200);
PropertyValuesHolder pv4 = PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);
//将所有的组合动画添加到ObjectAnimator中
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(iv, pv1, pv2, pv3, pv4);
oa.setDuration(5000);
oa.start();
8、在XML中使用属性动画
要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。
可以使用如下三种标签:
- animator:对应代码中的ValueAnimator
- objectAnimator:对应代码中的ObjectAnimator
- set:对应代码中的AnimatorSet
属性 | 功能 | 适用对象 |
---|---|---|
android:interpolator | 动画运动的插值器 可以匀速、加速、减速或抛物线速度等各种速度变化 |
animator objectAnimator |
android:duration | 持续的时间,单位为毫秒 | animator objectAnimator |
android:valueFrom | 动画开始的值 | animator objectAnimator |
android:valueTo | 动画结束的值 | animator objectAnimator |
android:valueType | valueFrom和valueTo的数据类型 | animator objectAnimator |
android:startOffset | 动画开始延迟时间 | animator objectAnimator |
android:repeatCount | 动画的重复次数,播放次数=重复次数+1。 可以是infinite(无限循环) |
animator objectAnimator |
android:repeatMode | 动画的重复方式。 可为reverse(反向)或restart(重新开始)(默认) |
animator objectAnimator |
android:propertyName | 动画属性的名称 | objectAnimator |
android:ordering | 执行顺序。 可为together(同时执行)或sequentially(顺序执行) |
set |
animator
//1、在res/animator目录下创建xml文件
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="360"
android:duration="2000"
android:valueType="intType">
</animator>
//2、在代码中加载动画文件
//加载动画
ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);
//作用对象
animator.setTarget(imageView);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int rotation = (int) animation.getAnimatedValue();
imageView.setRotation(rotation);
}
});
//开始动画
animator.start();
objectAnimator
//1、在res/animator目录下创建xml文件
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="5000">
</objectAnimator>
//2、在代码中加载动画文件
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.object_animator);
animator.setTarget(imageView);
animator.start();
set
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<set android:ordering="together">
<objectAnimator
android:propertyName="rotationY"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="360"
android:duration="5000"/>
<objectAnimator
android:propertyName="scaleX"
android:valueType="floatType"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="5000"/>
<objectAnimator
android:propertyName="scaleY"
android:valueType="floatType"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="5000"/>
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0.2"
android:valueTo="1"
android:duration="5000"/>
</set>
<set android:ordering="sequentially">
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="-300"
android:duration="1000"/>
<objectAnimator
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="600"
android:duration="1000"/>
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="-300"
android:valueTo="300"
android:duration="1000"/>
<objectAnimator
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="600"
android:valueTo="0"
android:duration="1000"/>
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="300"
android:valueTo="0"
android:duration="1000"/>
</set>
</set>