属性动画中最基础的 ObjectAnimator
ObjectAnimator
是属性动画中最重要的实行类,创建一个ObjectAnimator
只需要通过他的静态工厂方类直接返回一个ObjectAnimator
对象。参数包括一个对象和对象的属性名字,但这个属性必须有get
和set
函数,内部会通过反射机制来调用set函数修改对象属性值,也可以调用setInterpolator
设置对应的差值器。
属性动画操作的是属性,所以被操作的view可以响应事件。
例子:实现平移动画
ObjectAnimator animator = ObjectAnimator.ofFloat(
view,
"translationX",
300
);
animator.setDuration(300);
animator.start();
- 第一个参数是要操纵的
View
- 第二个参数是要操作的属性
- 第三个是一个可变数组参数,需要穿进去该属性变化的一个取值过程,这里就是变化到300
- 下面是给动画设置时长,差值器等属性
注意到ofFloat
方法,这是源码中的注释
/**
* Constructs and returns an ObjectAnimator that animates between float values. A single
* value implies that that value is the one being animated to. Two values imply starting
* and ending values. More than two values imply a starting value, values to animate through
* along the way, and an ending value (these values will be distributed evenly across
* the duration of the animation).
*
* @param target The object whose property is to be animated. This object should
* have a public method on it called <code>setName()</code>, where <code>name</code> is
* the value of the <code>propertyName</code> 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.
*/
大概意思是:
/**
* 构造并返回一个浮点值之间的动画ObjectAnimator。单
* 值意味着该值被动画的之一。两个值意味着启动
* 和结束值。多于两个值意味着一个起始值,值动画通过
* 一路走来,和结束值(这些值将均匀分布在整个
* 动画的持续时间)。
*
* @参数target其属性是动画的对象。这个对象应该
* 有它的公共方法叫做<代码>的setName()</代码>,其中<代码>名称</ code>的是
* 在<code>的值propertyname</ code>的参数。
* @参数PROPERTYNAME被动画的属性的名称。
* @参数值一组动画将随着时间的推移之间的动画值。
* 返回:已设置给定的值之间设置动画的ObjectAnimator对象。
*/
在使用ObjectAnimator
的时候要注意的就是属性必须有get
和set
方法,否则ObjectAnimator
就无法生效。下面是常用的可以直接使用属性动画的属性值:
-
translationX
和translationY
:这两个属性作为一种增量来控制着View
对象从它布局容器左上角坐标偏移的位置。 -
rotation,rotationX,rotationY
:这三个属性控制View对象围绕支点进行2D和3D旋转。 -
scaleX,scaleY
:这两个属性控制View
对象围绕它的支点进行2D缩放。 -
pivotX,pivotY
:这两个属性控制着View
对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,支点是View
对象的中心点。 -
x
和y
:这是两个简单实用的属性,它描述了View对象在它容器中的最终位置,它是最初左上角坐标和translationX、translationY
值的累计和。 -
alpha
:它表示View
对象的alpha
透明度。默认是1(不透明),0代表完全透明(不可见)
如果一个属性没有有get
和set
方法,有两种解决方法。
- 通过自定义一个属性类或包装类来间接给这个属性添加
get、set
方法。 - 通过ValueAnimator实现
第一种,通过自定义一个属性类或包装类来间接给这个属性添加get、set
方法:
WrapperView wrapper = new WrapperView(view);
ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
private static class WrapperView {
private View mTarget;
public WrapperView(View mTarget) {
this.mTarget = mTarget;
}
public int getWidth() {
return mTarget.getLayoutParams().width;
}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
PropertyValuesHolder
如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder
来实现,比如在平移中,同时改变X、Y
轴的缩放,可以这样实现:
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000).start();
ValueAnimator
ValueAnimator
本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字。从而让调用者控制动画的实现过程,ValueAnimator
的一般使用方法如下:
ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(5000).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
//TODO use the value
Log.i("MainActivity", "value = " + value);
}
});
其中AnimatorUpdateListener
监听数值的变换,从而完成动画的变换,这个例子中,value输出的是从0到100
动画事件监听
一个完整的动画监听包括四个过程:
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
但是大部分时候,我们只关心onAnimationEnd
事件,所以还可以这样通过AnimatorListenerAdapter
选择想要的事件进行监听:
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
AnimatorSet
对于一个属性同时作用多个属性动画效果,除了使用PropertyValuesHolder
外,还可以使用AnimatorSet
,而且AnimatorSet
还可以实现更为精确的顺序控制。
ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
set.start();
在属性动画中,AnimatorSet
通过playTogether();playSequentially();set.play().with();set.play().before();set.play().after();
这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。
网友评论