属性动画

作者: 翻身不做咸鱼 | 来源:发表于2016-09-13 00:02 被阅读141次

    上一篇我们总结了补间动画,接下来我们来总结一下属性动画的用法。
    自从android3.0 之后又有了属性动画PropertyAnimation。属性动画的实现机制是通过对目标对象进行赋值并修改其“属性”来实现的,这个怎么理解呢?假如我们通过属性动画来移动一个textview,那么这个textview就是真正的移动了,而不再是仅仅在另外一个位置绘制了而已,即是控件的真实位置移动了,而补间动画则是在另外一个地方绘制了一个一模一样的而已,真实位置还是在原来的地方。

    ValueAnimator
    ValueAnimator是整个属性动画机制当中最核心的一个类,前面我们已经提到了,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。

    *ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f); *然后再开启动画即可。当然ValueAnimtor还有两个常用方法,即:ValueAnimator.ofInt(),ValueAnimator.ofObject(),除此之外,我们还可以调用setStartDelay()方法来设置动画延迟播放的时间,调用setRepeatCount()和setRepeatMode()方法来设置动画循环播放的次数以及循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思。

    下边通过一个例子来介绍valueAnimator的使用:

     private void vlueAnim() {
            ValueAnimator anmator = ValueAnimator.ofFloat(1f, 0f, 1f, 0f);
            anmator.setStartDelay(1000); //设置延时1秒后开始动画
            anmator.setDuration(5000);
            anmator.setRepeatCount(10);
            anmator.setRepeatMode(ValueAnimator.RESTART);
            anmator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (float) animation.getAnimatedValue();
                    tv.setAlpha(value);//动态更新textview的透明值
                }
            });
            anmator.start();
        }
    

    这就是在监听器中通过得到的动画值的变化来更新View的相关属性,从而有动画效果。
    效果如下:


    Animatorvalue.gif

    ObjectAnimator
    ObjectAnimator与ValueAnimator的区别:
    1、构造方法与ObjectAnimator类似,ObjectAnimator继承自ValueAnimtor。
    2、与ObjectAnimator的区别在于ValueAnimator构造函数的参数中不包含执行该动画“属性”信息和对象,只有动画的值变化起始值和结束值。
    3、优点:结合动画更新监听onAnimationUpdate使用,可以在回调中不断更新View的多个属性,使用起来更加灵活。

    ObjectAnimator可能才是我们最常接触到的类,因为ValueAnimator只不过是对值进行了一个平滑的动画过渡。而ObjectAnimator则就不同了,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。
    不过虽说ObjectAnimator会更加常用一些,但是它其实是继承自ValueAnimator的,底层的动画实现机制也是基于ValueAnimator来完成的,因此ValueAnimator仍然是整个属性动画当中最核心的一个类。那么既然是继承关系,说明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的。

    将textview 在3秒内,由常规变为透明再变为常规:

    ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "alpha", 1f,  0f, 1f);
            anim.setDuration(3000);//持续时间  
            anim.start();
    

    将textview 在5秒内360度旋转:

    ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "rotation", 0f,  360f);
            anim.setDuration(3000);
            anim.start();
    

    实现复合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
    after(Animator anim) 将现有动画插入到该传入的动画(就是anim)之后执行
    after(long delay) 将现有动画延迟指定毫秒后执行
    before(Animator anim) 将现有动画插入到该传入的动画(就是anim)之前执行
    with(Animator anim) 将现有动画和传入的动画同时执行

    好的,有了这四个方法,我们就可以实现复合动画了,先向上平移,然后旋转同时改变透明值和缩放,就可以这样做:

    private void objectAnim() {
            ObjectAnimator anim1 = ObjectAnimator.ofFloat(tv1, "alpha", 0.5f, 1f, 0.5f, 1f);
            ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
            ObjectAnimator anim3 = ObjectAnimator.ofFloat(tv1, "scaleY", 1f, 3f, 1f);
            ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationY", 0f, -100f); //Y轴平移
    //        ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationX", 0f, 50f); //X轴平移
            AnimatorSet animset = new AnimatorSet(); //定义一个AnimatorSet对象
            animset.play(anim1).with(anim2).with(anim3).after(anim4);  //先执行anim4,再同时执行anim1、anim2、anim3
            animset.setDuration(6000);
            animset.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                //动画开始,do sthing...  
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
               //动画结束,do sthing...  
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
    
                }
            });
    //        animset.setInterpolator(new OvershootInterpolator());
            animset.start();
        }
    

    效果如下:

    ObjectAnimator.gif

    在很多时候,我们希望可以监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理。这个功能是完全可以实现的,Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。
    大家已经知道,ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法的。另外AnimatorSet也是继承自Animator的,因此addListener()这个方法算是个通用的方法。属性动画的基本用法就是这些了.不仅补间动画可以使用插值器,当然属性动画也可以加入插值器动画。

    Paste_Image.png

    加入插值器:

      TranslateAnimation down = new TranslateAnimation(0, 0, -300, 0);//位移动画,从button的上方300像素位置开始
            down.setFillAfter(true);//设置动画固定结束后位置
            down.setInterpolator(new BounceInterpolator()); //弹跳动画,要其它效果的当然也可以设置为其它的值
            down.setDuration(2000); //持续时间
            btn_login.startAnimation(down);
            btn_register.startAnimation(down);
    

    效果如下:


    加入插值器.gif

    更多插值器的用法可以用时候在慢慢了解。。。

    git上源码地址请点击

    相关文章

      网友评论

        本文标题:属性动画

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