属性动画相关内容可参考官网
动画资源
属性动画概览
来自官网的说明,
属性动画与视图动画的区别
视图动画系统仅提供为 View 对象添加动画效果的功能,因此,如果您想为非 对象添加动画效果,则必须实现自己的代码才能做到。视图动画系统也存在一些限制,因为它仅公开 对象的部分方面来供您添加动画效果;例如,您可以对视图的缩放和旋转添加动画效果,但无法对背景颜色这样做。
视图动画系统的另一个缺点是它只会在绘制视图的位置进行修改,而不会修改实际的视图本身。例如,如果您为某个按钮添加了动画效果,使其可以在屏幕上移动,该按钮会正确绘制,但能够点击按钮的实际位置并不会更改,因此您必须通过实现自己的逻辑来处理此事件。
有了属性动画系统,您就可以完全摆脱这些束缚,还可以为任何对象(视图和非视图)的任何属性添加动画效果,并且实际修改的是对象本身。属性动画系统在执行动画方面也更为强健。概括地讲,您可以为要添加动画效果的属性(例如颜色、位置或大小)分配 Animator,还可以定义动画的各个方面,例如多个 Animator 的插值和同步。
不过,视图动画系统的设置需要的时间较短,需要编写的代码也较少。如果视图动画可以完成您需要执行的所有操作,或者现有代码已按照您需要的方式运行,则无需使用属性动画系统。在某些用例中,也可以针对不同的情况同时使用这两种动画系统。
开始使用。
单个动画使用 ObjectAnimator
,复合动画使用 AnimatorSet
。
动画 Demo 和前篇 Android View动画整理 一致,动画作用在图片上。图片显示在左上角,图片右侧和下方的线是为了方便看出 View 动画前后的位置、大小对比,无实际作用。
平移
改变对象的 translationX 、translationY 属性。
Java 方式
向右平移自身宽度的距离。
import android.animation.ObjectAnimator;ObjectAnimator animatorTranX = ObjectAnimator.ofFloat(imageView, "translationX", 0 , imageView.getWidth());
animatorTranX.setDuration(3000);
animatorTranX.start();
向下平移自身高度的距离。
ObjectAnimator animatorTranY = ObjectAnimator.ofFloat(imageView, "translationY", 0 , imageView.getHeight());
animatorTranY.setDuration(3000);
animatorTranY.start();
多个动画同时播放,就用AnimatorSet.playTogether(Animator... items)
,
可以通过 ObjectAnimator.setInterpolator(TimeInterpolator value)
设置动画插值器 ,
/*** The time interpolator used in calculating the elapsed fraction of this animation. The* interpolator determines whether the animation runs with linear or non-linear motion,* such as acceleration and deceleration. The default value is* {@link android.view.animation.AccelerateDecelerateInterpolator}** @param value the interpolator to be used by this animation. A value of <code>null</code>* will result in linear interpolation.*/@Overridepublic void setInterpolator(TimeInterpolator value) {if (value != null) {mInterpolator = value;} else {mInterpolator = new LinearInterpolator();}}
ObjectAnimator animatorTranX = ObjectAnimator.ofFloat(imageView, "translationX", 0 , imageView.getWidth());
ObjectAnimator animatorTranY = ObjectAnimator.ofFloat(imageView, "translationY", 0 , imageView.getHeight());
AnimatorSet setTranslate = new AnimatorSet();
setTranslate.playTogether(animatorTranX, animatorTranY);
setTranslate.setDuration(3000);
setTranslate.start();
同时播放的效果:
多个动画先后播放,就用 play(Animator anim)
、 after(Animator anim)
、before(Animator anim)
,
如,先播放向右平移动画再播放向下平移动画。
ObjectAnimator animatorTranX = ObjectAnimator.ofFloat(imageView, "translationX", 0 , imageView.getWidth());
ObjectAnimator animatorTranY = ObjectAnimator.ofFloat(imageView, "translationY", 0 , imageView.getHeight());
AnimatorSet setTranslate = new AnimatorSet();
setTranslate.play(animatorTranY).after(animatorTranX);
setTranslate.setDuration(3000);
setTranslate.start();
先后播放的效果:
xml 方式
也可以使用 xml 的方式。
创建 res/animator 目录,
创建 res/animator/object_animator_set_translate.xml 文件(名字可以自己取)
Root element 可选 set 、objectAnimator 。set 是复合动画, objectAnimator 是单个动画。建议 set ,毕竟 set 里可以只放一个动画。
在 res/animator/object_animator_set_translate.xml 写入,
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"><objectAnimatorandroid:propertyName="translationX"android:valueTo="400dp"></objectAnimator><objectAnimatorandroid:propertyName="translationY"android:valueTo="200dp"></objectAnimator>
</set>
400dp 、200dp 分别是 imageView 的宽高。
Java 代码中通过 AnimatorInflater.loadAnimator(Context context, @AnimatorRes int id)
使用,
AnimatorSet.setTarget(Object target)
指定要进行属性动画的 Object 。
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;AnimatorSet setTranXml = (AnimatorSet) AnimatorInflater.loadAnimator(ObjectAnimActivity.this, R.animator.object_animator_set_translate);
setTranXml.setTarget(imageView);
setTranXml.setDuration(3000);
setTranXml.start();
这样就有效果了。
缩放、旋转、透明也类似,只是传的参数值不同。
缩放
改变对象的 scaleX、scaleY属性。
Java 方式
默认以中心点缩放
ObjectAnimator animatorScaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f , 0.5f);
ObjectAnimator animatorScaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f , 0.5f);AnimatorSet setScale = new AnimatorSet();
setScale.playTogether(animatorScaleX,animatorScaleY);
setScale.setDuration(3000);
setScale.start();
效果:
通过 setPivotX
、setPivotY
来设置中心点,以右下角为中心点缩放,
ObjectAnimator animatorScaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f , 0.5f);
ObjectAnimator animatorScaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f , 0.5f);
imageView.setPivotX(imageView.getWidth());
imageView.setPivotY(imageView.getHeight());AnimatorSet setScale = new AnimatorSet();
setScale.playTogether(animatorScaleX,animatorScaleY);
setScale.setDuration(3000);
setScale.start();
效果:
xml 方式
创建 res/animator/object_animator_set_scale.xml 文件,
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"><objectAnimator android:propertyName="scaleX" android:valueFrom="1" android:valueTo="0.5" android:duration="3000"/><objectAnimator android:propertyName="scaleY" android:valueFrom="1" android:valueTo="0.5" android:duration="3000"/>
</set>
Java 调用,
AnimatorSet setScaleXml = (AnimatorSet) AnimatorInflater.loadAnimator(ObjectAnimActivity.this, R.animator.object_animator_set_scale);
setScaleXml.setTarget(imageView);
setScaleXml.start();
旋转
改变对象的 rotation 属性。
Java 方式
默认以中心点旋转,
ObjectAnimator animatorRotate = ObjectAnimator.ofFloat(imageView, "rotation",0, 180);
animatorRotate.setDuration(2000);
animatorRotate.start();
效果:
通过 setPivotX
、setPivotY
来设置中心点,以右下角为中心点旋转,
ObjectAnimator animatorRotate = ObjectAnimator.ofFloat(imageView, "rotation",0, 180);
imageView.setPivotX(imageView.getWidth());imageView.setPivotY(imageView.getHeight());
animatorRotate.setDuration(2000);
animatorRotate.start();
效果:
xml 方式
创建 res/animator/object_animator_rotate.xml 文件,
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:propertyName="rotation"android:valueFrom="0"android:valueTo="180">
</objectAnimator>
Java 调用,
ObjectAnimator animatorRotateXml = (ObjectAnimator) AnimatorInflater.loadAnimator(ObjectAnimActivity.this, R.animator.object_animator_rotate);
animatorRotateXml.setTarget(imageView);
animatorRotateXml.start();
透明度
改变对象的 alpha 属性。
Java 方式
把透明度改为半透明。
ObjectAnimator animatorAlpha = ObjectAnimator.ofFloat(imageView, "alpha",1.0f, 0.5f);
animatorAlpha.setDuration(2000);
animatorAlpha.start()
效果:
xml 方式
创建 res/animator/object_animator_alpha.xml 文件,
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:propertyName="alpha"android:valueFrom="1"android:valueTo="0.5">
</objectAnimator>
Java 调用,
ObjectAnimator animatorAlphaXml = (ObjectAnimator) AnimatorInflater.loadAnimator(ObjectAnimActivity.this, R.animator.object_animator_alpha);
animatorAlphaXml.setTarget(imageView);
animatorAlphaXml.start();
对点击事件的影响
属性动画对点击事件有影响。
即对象的大小、位置变化后,点击对象的原始位置,点击事件没了。
点击对象属性动画结束的位置,点击事件可以响应。
示例,点击图片时弹个 Toast ,
动画插值器
通过动画插值器来控制动画效果,
ObjectAnimator animatorTranX = ObjectAnimator.ofFloat(imageView, "translationX", 0 , imageView.getWidth());
animatorTranX.setInterpolator(new LinearInterpolator()); //
animatorTranX.setDuration(3000);
animatorTranX.start();
AnimatorSet 可以统一设置动画插值器 , 也可以每个动画单独设置动画插值器
AnimatorSet animatorSet3 = new AnimatorSet();
animatorSet3.playTogether(animatorTranX3, animatorTranY3, animatorRotate3);
animatorSet3.setDuration(2500);
animatorSet3.setInterpolator(new LinearInterpolator()); //
animatorSet3.start();
动画 xml 中也可以指定,
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"><objectAnimatorandroid:duration="3000"android:interpolator="@android:interpolator/linear"android:propertyName="scaleX"android:valueFrom="1"android:valueTo="0.5" /><objectAnimatorandroid:duration="3000"android:interpolator="@android:interpolator/accelerate_decelerate"android:propertyName="scaleY"android:valueFrom="1"android:valueTo="0.5" />
</set>