Property Animation 的框架弥补了View Animation的一些短板,我们可以借助属性动画完成一些复杂的动画效果,做出一些酷炫的UI交互。
Property Animation故名思议就是通过动画的方式改变对象的属性了,我们首先需要了解几个API:
LinearInterpolator
、AccelerateDecelerateInterpolator
,大家一定知道是干嘛的了,定义动画的变化率。 这篇先介绍 ObjectAnimator
动画执行类。
再了解几个新加的属性:
translationX 和 translationY
:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。 rotation, rotationX 和 rotationY
:控制View绕着轴点(pivotX和pivotY)旋转。 scaleX 和 scaleY
:控制View基于pivotX和pivotY的缩放。 pivotX 和 pivotY
:旋转的轴点和缩放的基准点,默认是View的中心点。 x 和 y
:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。 aplha
:透明度,1是完全不透明,0是完全透明。 xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="scaleX"
android:duration="2000"
android:valueFrom="1.0"
android:valueTo="2.0"
android:repeatCount="1"
android:repeatMode="reverse">
objectAnimator>
在XML中要利用 objectAnimator
来定义我们的某个属性的效果,所以:
propertyName
: 理论上这个属性的值可以是对象中的任何有get/set方法的属性,不过我们这里是对View来说,所以一般而言,就是上面新加的那几种新属性了。duration
: 持续时间valueFrom 和 valueTo
:属性在动画开始和结束时相对应的值,如果我们是缩放的话,就代表倍数,如果是平移(Translation)的话,那么就代表距离了。4)repeatCount 和 repeatMode
:这两个和View Animation 中是一样的,就不多说了。
在xml中定义好了之后,接下来就要在Java中调用了,如下:
//利用AnimationInflater类的loadAnimator方法来获取我们的ObjectAnimator对象
ObjectAnimator scaleXAnimator = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.scalex);
//利用setTarget(View)方法来设置这个动画应用的对象
scaleXAnimator.setTarget(mView);
//调用其start方法触发动画效果
scaleXAnimator.start();
当动画效果开始后,我们发现它就只是在x方向上变大,Y方向并没有变化,在XML中一个ObjectAnimator只能对应于一个属性,所以下面就是Set的展现了,跟View Animation一样,set也是将几个效果给弄在一起,一次性执行也行,顺序执行也行,只要设置其ordering属性就好。
xml中:
xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="2000"
android:propertyName="scaleX"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="2.0" >
objectAnimator>
<objectAnimator
android:duration="2000"
android:propertyName="scaleY"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="2.0" >
objectAnimator>
set>
java中调用:
AnimatorSet animatorScaleSet = (AnimatorSet)AnimatorInflater.loadAnimator(this, R.animator.scale);
animatorScaleSet.setTarget(mView);
animatorScaleSet.start();
Java中提供多种方式定义动画:
OjbectAnimator
和 AnimatorSet
对象,并设置对应的参数和属性PropertyValuesHolder
或者 ViewPropertyAnimator
对象来实现(多动画简单)//绕X轴翻转360度
ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F)//
.setDuration(500)//
.start();
对于 ObjectAnimator
:
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// view.postInvalidate();
// view.invalidate();
}
});
ObjectAnimator anim = ObjectAnimator//
.ofFloat(view, "zhy", 1.0F, 0.0F)//
.setDuration(500);//
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
注:把设置属性的那个字符串,随便写一个该对象没有的属性,就是不管~咱们只需要它按照时间插值和持续时间计算的那个值,我们自己手动调用
AnimatorSet animationSet = new AnimatorSet();
animationSet.playTogether( //一起执行
ObjectAnimator.ofFloat(mView, "alpha", 1,0,1), //透明度变化
ObjectAnimator.ofFloat(mView, "translationX", 0f,400f,0f), //X平移变化
ObjectAnimator.ofFloat(mView, "rotation", 0,180,360) //翻转变化
);
animationSet.setDuration(1000);
animationSet.addListener(new AnimatorListener() { //动画监听
@Override
public void onAnimationStart(Animator arg0) {}
@Override
public void onAnimationRepeat(Animator arg0) {}
@Override
public void onAnimationEnd(Animator arg0) {}
@Override
public void onAnimationCancel(Animator arg0) {}
});
animationSet.start();
1)通过ObjectAnimator的工厂方法创建多个ObjectAnimator:
target
:动画效果的实施对象。propertyName
:对应的属性,如alpha,translationX等等values
:这是一组值,就是由什么值变动到另外一个什么值可以从源码看到 ObjectAnimator
方法接收的参数类型:
* @param target The object whose property is to be animated. This object should
* have a public method on it called setName()
, where name
is
* the value of the propertyName
parameter.
* @param propertyName The name of the property being animated.
* @param values A set of values that the animation will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setFloatValues(values);
return anim;
}
2)然后通过 AnimatorSet的playTogether方法或者playAfter, playBefore等方法将其加入到set中。
3)给set设置相对应的如duration之类的属性
4)我们还能够给Animator添加一个Listener,让它能够对Animator的几个关键点进行响应,分别是开始,结束,重复,取消时的响应函数,在这里有一点要注意的就是:
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator){
final Button button = (Button) findViewById(R.id.buttonViewPropAnimator);
button.animate().alpha(1).translationX(0f).start();
}
})
4)执行start方法开始动画。
除了Set,我们还可以利用 PropertyValuesHolder
和 ViewPropertyAnimator
对象来实现,具体做法如下:
PropertyValuesHolder
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX",0f,300f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY",0f,300f);
ObjectAnimator translateAnimator = ObjectAnimator.ofPropertyValuesHolder(mView, pvhX, pvhY);
translateAnimator.setDuration(2000);
translateAnimator.start();
1)我们可以通过 PropertyValuesHolder
类的工厂方法 ofInt
, ofFloat
等方法,让它能够Hold住对应 property 的 value 。
2)在利用 ObjectAnimator
的 ofPropertyValuesHolder
方法时,再将我们上面定义的 propertyValuesHolder
给传进去,定义出一个 objectAnimator
。
3)设置 objectAnimator
对应的属性,调用其 start
方法就行。
mView.animate().translationX(100f).alpha(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator){
final Button button = (Button) findViewById(R.id.buttonViewPropAnimator);
button.animate().alpha(1).translationX(0f).start();
}
}).start();