Android属性动画之ObjectAnimator使用

前面一文讲解了Android属性动画之ValueAnimator使用,我们知道ValueAnimator可以对数值进行动态变化,或者对对象进行变化,这里继续来了解一下ValueAnimator的子类ObjectAnimator。

推荐博客:http://blog.csdn.net/guolin_blog/article/details/43536355

ObjectAnimator相对其父类,功能更加强大了,可以对一个对象的属性进行动画操作。比如说View的alpha属性。

下面就看一下ObjectAnimator的一些用法:

 ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"alpha",1f,0f,1f);
                animator.setDuration(4000);
                animator.start();



可以看到,我们还是调用了ofFloat()方法来去创建一个ObjectAnimator的实例,只不过ofFloat()方法当中接收的参数有点变化了。这里第一个参数要求传入一个object对象,我们想要对哪个对象进行动画操作就传入什么,这里我传入了一个textview。第二个参数是想要对该对象的哪个属性进行动画操作,由于我们想要改变TextView的透明度,因此这里传入"alpha"。后面的参数就是不固定长度了,想要完成什么样的动画就传入什么值,这里传入的值就表示将TextView从常规变换成全透明,再从全透明变换成常规。之后调用setDuration()方法来设置动画的时长,然后调用start()方法启动动画,看一下动画效果:

Android属性动画之ObjectAnimator使用_第1张图片

这里我们需要考虑第二个参数属性到底该传什么值,为什么我们传入“alpha”,ObjectAnimator就会去改变textView的透明度呢?

传入的属性与传入的对象是关联的。ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法,如果这个对象都没有这个属性对应的get和set方法,那么是看不到对象的显示效果有变化,但是传入的值还是会变化的。

我们可以来看测试一下:

  ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"xxx",1f,0f,1f);
                animator.setDuration(1000);
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float value = (float) animation.getAnimatedValue();
                        Log.d("Test", "cuurent value is " + value);
                    }
                });
                animator.start();

这里属性名就瞎传了“xxx”在TextView的类及父类里肯定没有这个属性对应的set和get方法,咱看一下效果:

Android属性动画之ObjectAnimator使用_第2张图片

点击没有任何效果

看log:

D/Test: cuurent value is 1.0
D/Test: cuurent value is 1.0
D/Test: cuurent value is 0.9985742
D/Test: cuurent value is 0.9943008
D/Test: cuurent value is 0.98768836
D/Test: cuurent value is 0.9779293
D/Test: cuurent value is 0.9653816
D/Test: cuurent value is 0.9510565
D/Test: cuurent value is 0.93320465
D/Test: cuurent value is 0.91269153
D/Test: cuurent value is 0.8910065
D/Test: cuurent value is 0.8655012
D/Test: cuurent value is 0.837528
D/Test: cuurent value is 0.8090169
D/Test: cuurent value is 0.7764865
D/Test: cuurent value is 0.74174184
D/Test: cuurent value is 0.70710677
D/Test: cuurent value is 0.6683521
D/Test: cuurent value is 0.62769127
D/Test: cuurent value is 0.58778536
D/Test: cuurent value is 0.5437604
D/Test: cuurent value is 0.49818516
D/Test: cuurent value is 0.45399046
D/Test: cuurent value is 0.40577984
D/Test: cuurent value is 0.3564117
D/Test: cuurent value is 0.30901706
D/Test: cuurent value is 0.25780725
D/Test: cuurent value is 0.20586258
D/Test: cuurent value is 0.1564343
D/Test: cuurent value is 0.103486896
D/Test: cuurent value is 0.05024445
D/Test: cuurent value is 0.0
D/Test: cuurent value is 0.053381562
D/Test: cuurent value is 0.106610894
D/Test: cuurent value is 0.1564343
D/Test: cuurent value is 0.20893562
D/Test: cuurent value is 0.2608415
D/Test: cuurent value is 0.30901706
D/Test: cuurent value is 0.35934532
D/Test: cuurent value is 0.4086492
D/Test: cuurent value is 0.45399046
D/Test: cuurent value is 0.5009067
D/Test: cuurent value is 0.54639435
D/Test: cuurent value is 0.58778536
D/Test: cuurent value is 0.63013387
D/Test: cuurent value is 0.6706855
D/Test: cuurent value is 0.7071068
D/Test: cuurent value is 0.743845
D/Test: cuurent value is 0.7784622
D/Test: cuurent value is 0.80901694
D/Test: cuurent value is 0.8392403
D/Test: cuurent value is 0.8670707
D/Test: cuurent value is 0.89100647
D/Test: cuurent value is 0.91397095
D/Test: cuurent value is 0.93432903
D/Test: cuurent value is 0.9510565
D/Test: cuurent value is 0.9661963
D/Test: cuurent value is 0.97858095
D/Test: cuurent value is 0.9876883
D/Test: cuurent value is 0.9946308
D/Test: cuurent value is 0.998737
D/Test: cuurent value is 1.0

可以看到传入的属性名称就算该对象没有对应get和set方法,也不会报错,而且还会计算值的变化。

那么TextView 是不是有"alpha"对应的get和set方法呢?,这个我们可以查找一下:

在View类中这两个方法,TextView 是View子类,所以肯定没问题的。

public float getAlpha()
public void setAlpha(float alpha)
同样我们可以在View中找到以下这些方法:

public float getRotation()//旋转
public void setRotation(float rotation)
public float getTranslationX()//x方向平移
public void setTranslationX(float translationX)
public float getTranslationY()//y方向平移
public void setTranslationY(float translationY)
public float getScaleX()//x方向缩放
public void setScaleX(float scaleX)
public float getScaleY()//y方向缩放
public void setScaleY(float scaleY)
所以我们在View的子类进行操作时,可以传入这些属性名:rotation,translationX,scaleY......

关于操作这些属性的代码片段就没贴了。

ObjectAnimator大部分情况我们用来改变View的属性值产生动画效果。

和Animation动画一样,属性动画也可以同时进行多个动画,用AnimatorSet来实现

 float x1 = textView.getTranslationX();
                ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"alpha",1f,0f,1f);
                ObjectAnimator animator11 = ObjectAnimator.ofFloat(textView,"rotation",0f,360f);
                ObjectAnimator animator22 = ObjectAnimator.ofFloat(textView,"translationX",x1,x1+200f);
                AnimatorSet animatorSet = new AnimatorSet();
                animatorSet.play(animator11).with(animator).with(animator22);

                animatorSet.setDuration(4000);
                animatorSet.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                    }

                });
                animatorSet.start();
上面三个动画效果:透明度变化,旋转,x方向平移。

AnimatorSet这个类,有一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

  • after(Animator anim)   将现有动画插入到传入的动画之后执行
  • after(long delay)   将现有动画延迟指定毫秒后执行
  • before(Animator anim)   将现有动画插入到传入的动画之前执行
  • with(Animator anim)   将现有动画和传入的动画同时执行
看一下效果:

Android属性动画之ObjectAnimator使用_第3张图片


另外可以设置动画的监听器,在动画整个过程中,做些事情:

ValueAnimator.AnimatorUpdateListener
这个监听的回调方法
onAnimationUpdate(ValueAnimator animation)//可以获取实时变化的中间值
Animator.AnimatorListener
这个监听有以下几个回调
onAnimationCancel(Animator animation)//动画取消
onAnimationEnd(Animator animation)//动画结束
onAnimationRepeat(Animator animation)//动画重复开始
onAnimationStart(Animator animation)//动画开始

Animator.AnimatorPauseListener
这个监听有以下几个回调
onAnimationPause(Animator animation)//动画暂停
onAnimationResume(Animator animation)//动画继续

同样ObjectAnimator和AnimatorSet可以用xml实现。

在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:

  •  对应代码中的ValueAnimator
  •  对应代码中的ObjectAnimator
  •  对应代码中的AnimatorSet

那么比如说我们想要实现一个透明度值从0到1过渡的动画,在XML当中就可以这样写:




然后在代码中使用:

  Animator animator = AnimatorInflater.loadAnimator(this, R.animator.object_animator);
                animator.setTarget(textView);
                animator.start();

关于ObjectAnimator就记录这些,当然这只是一些简单动画效果,可以使用TypeEvaluator实现更复杂的动画效果。











你可能感兴趣的:(Android开发)