概述
随着移动互联网的快速发展,各种移动应用也层出不穷,在追求产品功能强大的同时,对界面的显示效果也越来越苛刻。动画已经成为了各种APP的重要组成部分,成为交互中不可分割的一部分。由于平时记录的知识点比较零碎,这次对它进行统一的整理,温故知新。
动画分类
Android 系统中提供了三种方式来实现动画效果,分别是帧动画(Frame/Drawable Animation ),补间动画(Tween/View Animation),属性动画(
Property Animation)。其中帧动画和补间动画是API 11 之前推出来的,属性动画是API 11之后推出的。它们中所含的知识点如下图所示(图来自网友),后面将分别介绍它们的用法。
帧动画(Frame Animation)
Frame animation 在SDK中,称为Drawable Animation。它就像GIF图片一样,通过一系列Drawable图片资源依次显示来模拟动画的效果。
Java中对应的类为:AnimationDrawable
实现步骤:
1.在目录res/drawable 中建立资源文件。(以前是在res/anim 中,使用Android Studio中要放在drawable目录下,否则报错)
如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/blank01" android:duration="200" />
<item android:drawable="@drawable/blank02" android:duration="200" />
<item android:drawable="@drawable/blank03" android:duration="200" />
<item android:drawable="@drawable/blank04" android:duration="200" />
<item android:drawable="@drawable/blank05" android:duration="200" />
<item android:drawable="@drawable/blank06" android:duration="200" />
</animation-list>
注意:
1。 必须作为根元素;
2。android:oneshot true:只执行一次动画,false:循环执行;
3。 作为 子元素,引用一张静态图片,代表一帧独立的动画;
4。android:duration 输入整数,表示该帧显示的时长,单位为毫秒。
2.在View控件上设置动画效果。可以直接在XML中设置android:background,或者通过代码的方式设置setBackgroundResource。
3.代码调用,AnimationDrawable类控制动画播放
imageView = (ImageView) findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.run);
animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.start(); //播放
animationDrawable.stop(); //停止
补间动画(Tween Animation)
Tween 动画是通过对View进行一系列的图形变化操作来实现的效果,包括:缩放,平移,旋转,渐变。因为该操作是针对View控件上的操作,所以也称为View Animation。
下面将逐一介绍上述几种动画效果
1.在XML文件中定义动画
View 动画资源全部都是放在目录:res/anim 中;
建议文件命名方式为:[ alpha | rotate | scale | translate | set ]_anim.xml;
1.1 创建渐变(alpha)效果动画资源:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="false"
android:fromAlpha="1.0"
android:toAlpha="0.0">
<!--
浮点型值:
fromAlpha 属性为动画起始时透明度
toAlpha 属性为动画结束时透明度
说明:
0.0表示完全透明
1.0表示完全不透明
以上值取0.0-1.0之间的float数据类型的数字
长整型值:
duration 属性为动画持续时间
说明:
时间以毫秒为单位
布尔型值:
fillAfter 属性当设置为true,该动画效果在动画结束后被应用
-->
</alpha>
1.2 创建旋转(rotate)效果动画资源:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="true"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
<!--
属性:interpolator 指定一个动画的插值器
有三种动画插值器:
accelerate_decelerate_interpolator 加速-减速 动画插值器
accelerate_interpolator 加速-动画插值器
decelerate_interpolator 减速- 动画插值器
其他的属于特定的动画效果
浮点数型值:
fromDegrees 属性为动画起始时物件的角度
toDegrees 属性为动画结束时物件旋转的角度 可以大于360度
说明:
当角度为负数——表示逆时针旋转
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)
pivotX 动画相对于View的X坐标的开始位置
pivotY 动画相对于View的Y坐标的开始位置
说明: 以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性当设置为true,该动画效果在动画结束后被应用
-->
</rotate>
1.3 创建平移(translate)效果动画资源:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="true"
android:fromXDelta="-100"
android:fromYDelta="0"
android:toXDelta="200"
android:toYDelta="0">
<!--
整型值:
fromXDelta 属性为动画起始时 X坐标上的位置
toXDelta 属性为动画结束时 X坐标上的位置
fromYDelta 属性为动画起始时 Y坐标上的位置
toYDelta 属性为动画结束时 Y坐标上的位置
注意:
没有指定fromXType toXType fromYType toYType 时候,
默认是以自己为相对参照物
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性当设置为true,该动画效果在动画结束后被应用
-->
</translate>
1.4 创建缩放(scale)效果动画资源:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="false"
android:fromXScale="1"
android:fromYScale="1"
android:interpolator="@android:anim/decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0"
android:toYScale="0">
<!--
属性:interpolator 指定一个动画的插入器
有三种动画插入器:
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
浮点型值:
fromXScale 属性为动画起始时X坐标上的伸缩尺寸
toXScale 属性为动画结束时X坐标上的伸缩尺寸
fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
toYScale 属性为动画结束时Y坐标上的伸缩尺寸
说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
pivotX 动画相对于View的X坐标的开始位置
pivotY 动画相对于View的Y坐标的开始位置
说明:
以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用
-->
</scale>
1.5 创建set动画集合资源:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="true"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:shareInterpolator="true">
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="500"
android:toYDelta="0" />
<scale
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0"
android:toYScale="0" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
注意:set作为根元素是一个动画集合,里面可以包括rotate,translate,scale,alpha中一个或几个作为子节点。但是使用set时,如果想要动画执行后应用在View上,android:fillAfter需作为set的属性,否则不生效。
2.在Activity中调用XML文件中定义动画
Animation scaleAnimation = AnimationUtils.loadAnimation(this,R.anim.scale_anim);
imageView.startAnimation(scaleAnimation);
说明:与帧动画不同的是,通过AnimationUtils来加载动画xml资源,生成Animation 对象,最后通过startAnimation开始动画。
以上就完成了通过xml实现补间动画的应用,下面我们将继续总结使用Java代码的方式实现动画的应用。
3.使用JavaCode定义补间动画
上面几种动画操作类型中,都有相对应的类对象
res/anim中资源根节点
Java中操作类对象
scale ScaleAnimation
translate TranslateAnimation
rotate RotateAnimation
alpha AlphaAnimation
set AnimationSet
调用方法:
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 200.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
RotateAnimation rotateAnimation = new RotateAnimation(0.0f, +350.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
AnimationSet animationSet = new AnimationSet(true);
animationSet.setDuration(1000);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
开始调用:
imageView.startAnimation(animationSet);
监听补间动画的执行过程,精确控制动画:
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//动画开始
}
@Override
public void onAnimationEnd(Animation animation) {
//动画结束
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重新运行
}
});
属性动画(property Animation)
我们已经知道补间动画就是针对View进行一系列的动画操作,包括淡入淡出(alpha),缩放(scale),平移(translate),旋转(rotate)。 这些操作仅仅改变了View的显示效果并没有修改View的真实属性,如位置,宽高等。而属性动画(property Animation)能够真正改变对象的属性。
上面是属性动画中的五大核心类,最常使用的是:ValueAnimator,ObjectAnimator,AnimatorSet。
ValueAnimator:对值进行了一个平滑的动画过渡;
ObjectAnimator:它是可以直接对任意对象的任意属性进行动画操作的,但是作用的对象必须提供该属性的get和set方法;
AnimatorSet:同时操作一个或以上的属性动画,按照特定顺序执行的动画集合,作用与AnimationSet 类似,但用法不同;
1.在XML文件中定义属性动画
与补间动画不同的是,属性动画资源全部都是放在目录:res/animator 中;
建议文件命名方式为:[ value | objectvalue | set ]_animator.xml;
在XML文件中我们一共可以使用如下三种标签;
对应代码中的ValueAnimator
对应代码中的ObjectAnimator
对应代码中的AnimatorSet
1.1.1 创建ValueAnimator 对应的资源文件
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:repeatCount="3"
android:repeatMode="restart"
android:startOffset="2000"
android:valueFrom="#000000"
android:valueTo="#FF3DFF"
android:valueType="colorType">
<!--
属性说明:
duration 动画的时长,int类型,以毫秒为单位,默认为300毫秒。
repeatCount 一个动画的重复次数,int型
说明:
-1 表示无限循环
1 表示动画在第一次执行完成后重复执行一次
0 默认值,不重复执行
repeatMode 重复模式
说明:
reverse 会使得按照动画向相反的方向执行。
repeat 会使得动画每次都从头开始循环。
startOffset 动画延迟的时间,从调用start方法后开始计算,int型,毫秒为单位
valueFrom 动画的起始点,Float、int或者color,也是必须值,颜色由6位十六进制的数字表示
valueTo 动画结束的点
valueType 关键参数,说明动画操作值的类型,valueFrom,valueTo的值类型要与之对应
说明:
colorType 颜色的变化
intType 整数的变化
floatType 小数的变化
pathType 路径的变化,5.0L新特性,配合VectorDrawable使用
-->
</animator>
上面xml文件中表示的是,颜色在500毫秒中的渐变。
1.1.2 在代码中调用animator资源文件
ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.value_animator);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
number.setBackgroundColor((Integer) animation.getAnimatedValue());
}
});
animator.start();
注意:与View animation不同的是,加载属性动画资源是通过类AnimatorInflater,生成的对象为Animator。
1.1.3 创建objectAnimator对应的资源文件
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="translationX"
android:repeatCount="3"
android:repeatMode="restart"
android:startOffset="1000"
android:valueFrom="0.0f"
android:valueTo="300.0f"
android:valueType="floatType">
<!--
属性说明:
objectAnimator 中有一个特殊的属性:
propertyName
String类型,必须要设定的值,代表要执行动画的属性。
动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新对象的某个属性,对象必须得有getter和setter方法,
这个objectAnimator元素没有暴露target属性,因此比不能够在XML中执行一个动画,
必须通过调用loadAnimator() 填充你的XML动画资源,并且调用setTarget() 应用到拥有这个属性的目标对象上。
-->
</objectAnimator>
1.1.4 在代码中调用objectAnimator资源文件
Animator objectAnimator = AnimatorInflater.loadAnimator(this,R.animator.valueobject_animator);
objectAnimator.setTarget(imageView);
objectAnimator.start();
注意:在加载objectAnimator 的资源后,需要设置setTarget,这样才能关联到View,更新View的属性。
1.1.5 创建AnimatorSet对应的资源文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="100"
android:propertyName="translationX"
android:startOffset="1000"
android:valueFrom="0.0f"
android:valueTo="500.0f"
android:valueType="floatType" />
<set android:ordering="together">
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" />
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" />
</set>
</set>
如上,在set中可以同时执行几个不同的动画效果,属性android:ordering=”together” 用来控制动画的播放顺序。
1.1.6 在代码中调用AnimatorSet资源文件
Animator objectAnimator = AnimatorInflater.loadAnimator(this,R.animator.set);
objectAnimator.setTarget(imageView);
objectAnimator.start();
总结:从上面可以看出,除了ValueAnimator 需要转型为对应的ValueAnimator 之外,其他的都可以通过Animator 的对象操作。
2.用Java代码定义属性动画
2.1 定义ValueAnimator 对象
ValueAnimator animator = ValueAnimator.ofInt(1,100);
animator.setDuration(1000);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
number.setText(String.valueOf(animation.getAnimatedValue()));
}
});
animator.start();
2.2 定义ObjectAnimator 对象
ObjectAnimator animator = new ObjectAnimator();
animator.setDuration(500); //动画播放时长
animator.setPropertyName("translationX"); //设置需要修改的属性
animator.setTarget(imageView); //修改属性的对象
animator.setFloatValues(0, 500,0); //修改的属性值范围
animator.setStartDelay(2000); //动画延迟多长后开始
animator.start(); //开始动画
2.3 定义AnimatorSet对象
ObjectAnimator translation = new ObjectAnimator();
translation.setPropertyName("translationX");
translation.setFloatValues(0, 500);
ObjectAnimator rotation = new ObjectAnimator();
rotation.setPropertyName("rotationX");
rotation.setFloatValues(0, 360);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(translation).with(rotation);
animatorSet.setDuration(500);
animatorSet.setStartDelay(1000);
animatorSet.setTarget(imageView);
animatorSet.start();
注意:
after(Animator anim) 将现有动画插入到传入的动画之后执行
after(long delay) 将现有动画延迟指定毫秒后执行
before(Animator anim) 将现有动画插入到传入的动画之前执行
with(Animator anim) 将现有动画和传入的动画同时执行
3.添加属性动画监听器
animatorSet.addListener(new AnimatorListenerAdapter());
animatorSet.addListener(new AnimatorListener());
注意:AnimatorSet 和 AnimationSet的区别
1.AnimatorSet 是属性动画的集合,AnimationSet 用于补间动画的集合;
2.AnimationSet :调用其 addAnimation 将一个个不一样的动画组织到一起来,然后调用view 的 startAnimation 方法触发这些动画执行。功能较弱不能做到把集合中的动画按一定顺序进行组织然后在执行的定制。 是针对视图外观的动画实现,动画被应用时外观改变但视图的触发点不会发生变化,还是在原来定义的位置。
AnimatorSet :我们最常用的是调用其play、before、with、after 等方法设置动画的执行顺序,然后调用其start 触发动画执行。是针对视图属性的动画实现,动画被应用时对象属性产生变化,最终导致视图外观变化。