Android 动画之属性动画(二)

作者: 梁加盐 | 来源:发表于2016-10-02 12:30 被阅读42次

    Android 动画之属性动画(二)#


    在这篇文章中将会通过介绍属性动画的具体使用

    Animating with ValueAnimator##

    首先需要获得一个ValueAnimator对象,它的获取方法是通过调用它的Factory Method: ofInt(int... values)ofFloat(float... values)ofObject(TypeEvaluator evaluator, Object... values) (int... values 表示传入的参数个数是任意的)

    更多关于 ValueAnimator 的方法请查看文档:
    https://developer.android.com/reference/android/animation/ValueAnimator.html

    ValueAnimator mValueAnimator = ValueAnimtor.ofInt(0,10);
    
    //ValueAnimator mValueAnimator = ValueAnimtor.ofInt(0,10,8,20);
    这样的意思是说从0过渡到10,然后在过渡到8,再过渡到20
    
    mValueAnimator.setDuration(200);
    mValueAnimator.setInterpolator(new LinearInterpolator());//设置均匀计算数值
    mValueAnimator.start();//通过start()来开始动画
    

    在上面的代码中,在start()方法启动后,ValueAnimator就会在200ms内,均匀地计算出0到10的int值,我们通过监听器来获取这些值,看看是否如上所描述的一样

    D/TAG: current value is 0
    D/TAG: current value is 2
    D/TAG: current value is 3
    D/TAG: current value is 4
    D/TAG: current value is 5
    D/TAG: current value is 5
    D/TAG: current value is 6
    D/TAG: current value is 7
    D/TAG: current value is 8
    D/TAG: current value is 9
    D/TAG: current value is 10

    可以看到基本是均匀增加的,出现误差的原因之前已经讲过,理论上来是每10ms更新一次,但是具体是取决于手机本身所能提供的计时器,因此这里我们看到的是接近每20ms更新一次,而且系统本身计时存在误差,因此也就出现了误差

    如果你想要进行动画的既不是整数值也不是浮点数值,那么就要用到 ofObject(TypeEvaluator evaluator, Object... values) ,比如说

    ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
    animation.setDuration(1000);
    animation.start();
    

    其中MyTypeEvaluator就是你自己定义的一个类型 ValueAnimator 只是为需要动画的属性提供一组平滑过渡的值,所以之后要需要为动画设置 监听 来得到这些值,然后在对具体的属性/对象利用这些值进行操作,有关 监听 的内容将在后面提到

    Animating with ObjectAnimator

    通常情况下我们用到更多的是 ObjectAnimator ,因为它可以直接指定你要进行动画的属性/对象。它的初始化方法和 ValueAnimator 的类似,不过它的方法中多了两个参数:ofFloat(Object target, String propertyName, float... values) ,第一个参数为你要进行动画的对象,第二参数为你要进行动画的属性值,比如说对象是一个TextView,你需要改变TextView的透明度这个属性.

    ObjectAnimator anim = ObjectAnimator.ofFloat(mTextView, "alpha", 0f, 1f);
    anim.setDuration(1000);
    anim.start();
    

    更多关于 ObjectAnimator 的方法请查看文档
    https://developer.android.com/reference/android/animation/ObjectAnimator.html

    要非常注意的一点是, ObjectAnimator 自动修改alpha其实是调用了TextView里面 setAlpha() 这个方法!因此,要对某一属性进行动画,那么目标对象一定要有 set< propertyName >() 这个方法

    我们来一起验证一下是否是这样:
    (1). 先来创建一个自定义的View,命名为myView,继承自TextView
    (2). 对它的透明度属性进行动画操作,一开始先不重写 setAlpha() 这个方法,来看看效果

    ObjectAnimator anim = ObjectAnimator.ofFloat(myview,"alpha",0f,1f);
    anim.setDuration(1000);
    anim.start();
    
    ----------
    
    @Override
    public void setAlpha(float alpha) {
        super.setAlpha(alpha);
    }
    

    (3). 然后我们重写 setAlpha() 这个方法,让他变成位移,看看效果

        @Override
        public void setAlpha(float alpha){
        super.setTranslationX(alpha*200);
        }
    

    可以看出,确实是调用了 myView 里面的setAlpha()方法

    假如你想要改变的属性没有对应的set方法,官方给出了这三种解决方法:

    • 假如你有修改这个对象的权限,那么你可以为这个对象添加setter方法
    • 使用一个你有权限去修改的 wrapper 类然后让这个 wrapper 类利用一个有效的setter方法来接收value,然后传递给对象
    • ValueAnimator 来替代

    Choreographing Multiple Animations with AnimatorSet

    很多情况下你不仅需要一个动画来满足你的需求,所以,你会要用到利用 AnimatorSet 类。它可以吧几个动画捆绑在一起,这样就可以控制这些动画是同时进行还是有序进行或者其他的。 AnimatorSet 可以互相嵌套。

    Animator 加到 AnimatorSet 里面有两种方法:
    (1). 利用 playTogether()playSequentially() ,一次处理完所有 Animator

    //假设前面已经创建了若干ValueAnimator/ObjectAnimator
    anim1,anim2,anim3
    
    //实例化一个AnimatorSet
    AnimatorSet aniset = new AnimatorSet();
    //调用 playTogether (Animator... items)
    aniset.playTogether(anim1,anim2,anim3);
    
    //你可以把这三个动画编成一个集合再调用
    playTogether(Collection<Animator> items),这里就不再演示 
    

    (2). 利用 Builder 里面的 play(),after(),before(),with() 方法来逐个添加动画,参数都是 Animator

     AnimatorSet s = new AnimatorSet();
     s.play(anim1).with(anim2);
     s.play(anim2).before(anim3);
     s.play(anim4).after(anim3);
    

    需要注意的是,AnimatorSet 最先使用的一定是 play() 因为只有 play() 的参数才是所有它紧接着的那个动画的主语,比如上面代码的第3行,before表示在之前发生,anim2 是主语,所以意思是 before(anim3) 的主语是 anim2anim2 将会在 anim3 发生前发生。再比如:

    AnimatorSet s = new AnimatorSet();
    s.play(anim1).before(anim2).before(anim3);
    

    这里无论是 before(anim2) 还是 before(anim3) 都是对于 anim1 来说的,所以在 anim1 结束后, anim2anim3 会同时开始。

    更多关于 AnimatorSet 的方法请查看文档
    https://developer.android.com/reference/android/animation/AnimatorSet.html#AnimatorSet()

    相关文章

      网友评论

        本文标题:Android 动画之属性动画(二)

        本文链接:https://www.haomeiwen.com/subject/osddyttx.html