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<Number>() { @Override public Number evaluate(float fraction, Number startValue,Number endValue) { // TODO Auto-generated method stub return null; } });上面就是实现的TypeEvaluator接口,下面有个未实现的方法,这个回调函数中提供如下三个参数: