public class MainActivity extends Activity {
private Button mButton;
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button);
mImageView = (ImageView) findViewById(R.id.imageview);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
playAnim();
}
});
mImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showToast();
}
});
}
/**
* 播放动画
*/
protected void playAnim() {
TranslateAnimation ta = new TranslateAnimation(0.0f, 200.0f, 0.0f, 0.0f);
ta.setDuration(1000);
ta.setFillAfter(true);
mImageView.startAnimation(ta);
}
protected void showToast() {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
}
}
类 | 描述 |
ValueAnimator | 属性动画时序引擎也计算属性动画的值。它拥有所有的核心功能,计算动画值,并包含每个动画,有关时序的详细信息是否动画重复,听众接收更新事件,并设置自定义类型的能力评估。有两件,以生动活泼的属性:动画值计算和设置这些对象的属性动画值。ValueAnimator不进行第二件,所以你一定要更新计算值ValueAnimator和修改你想用自己的逻辑动画的对象。 |
ObjectAnimator | ValueAnimator的子类,允许你设置一个目标对象和对象属性的动画。当计算出一个新的动画值,本类更新相应的属性。你大部分情况使用ObjectAnimator,因为它使得动画的目标对象的值更简单。然而,有时你直接使用ValueAnimator,因为ObjectAnimator有一些限制,如对目标对象目前要求的具体acessor方法。 |
AnimatorSet | 提供机制,以组合动画一起,让他们关联性运行。你可以设置动画一起播放,顺序,或在指定的延迟之后。 |
protected void playAnim() {
ObjectAnimator.ofFloat(mImageView, "translationX", 0.0f, 200.0f).setDuration(1000).start();
}
ObjectAnimator继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件:
如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。
protected void playAnim() {
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX",0.0f, 200.0f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY",0.0f, 200.0f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation",0.0f, 360.0f);
ObjectAnimator.ofPropertyValuesHolder(mImageView, p1, p2, p3).setDuration(2000).start();
}
protected void playAnim() {
Animator animator1 = ObjectAnimator.ofFloat(mImageView, "translationX",0.0f, 200.0f);
Animator animator2 = ObjectAnimator.ofFloat(mImageView, "translationY",0.0f, 200.0f);
Animator animator3 = ObjectAnimator.ofFloat(mImageView, "rotation",0.0f, 360.0f);
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2, animator3);
set.setDuration(2000);
set.start();
}
AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
以下例子同时应用5个动画:
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//动画开始时执行
}
@Override
public void onAnimationRepeat(Animator animation) {
//动画重复时执行
}
@Override
public void onAnimationEnd(Animator animation) {
//动画结束时执行
}
@Override
public void onAnimationCancel(Animator animation) {
//动画被取消时执行
}
});
Animator.AnimatorListener对象下,有4个未实现的方法,我们可以分别实现一下其中的方法,就可以方便的去监听动画执行整个过程了。但是Animator.AnimatorListener对象不够简洁,因为大部分时候我们只需要监听动画结束时的事件即可,那么Android也为我们提供好了一个简化的监听对象AnimatorListenerAdapter,AnimatorListenerAdapter
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
super.onAnimationEnd(animation);
}
});
ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。应用Property Animation有两个步聚:
ValuAnimiator只完成了第一步工作,如果要完成第二步,需要实现ValueAnimator.onUpdateListener接口,这个接口只有一个函数onAnimationUpdate(),在这个函数中会传入ValueAnimator对象做为参数,通过这个ValueAnimator对象的getAnimatedValue()函数可以得到当前的属性值如:
protected void playAnim() {
ValueAnimator animator = ValueAnimator.ofInt(0, 10);
animator.setDuration(100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("TAG", "AnimatedValue : " + animation.getAnimatedValue().toString());
}
});
animator.start();
}
从上面的例子可以看到ValueAnimator类实现的是动画的插值因子的计算,大部分情况下我们使用ObjectAnimator就可以轻松实现很多种动画效果了,然后使用ObjectAnimator的View必须满足有getter和setter方法,若没有这些方法,使用ObjectAnimator的动画是无法实现的,我们只好考虑使用ObjectAnimator的父类ValueAnimator了,ValueAnimator实现动画不需要View含有getter和setter方法,它是通过计算动画的插值因子,我们根据这个插值自定义动画效果就可以了。
TypeEvaluator是一个接口,通过实现该接口下的evaluate方法,可以实现我们自定义的各种复杂效果的动画:
ValueAnimator animator =ValueAnimator.ofObject(new TypeEvaluator() {
@Override
public Number evaluate(float fraction, Number startValue,Number endValue) {
// TODO Auto-generated method stub
return null;
}
});
上面就是实现的TypeEvaluator接口,下面有个未实现的方法,这个回调函数中提供如下三个参数: