Android属性动画(ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet)

Android属性动画

  在Animator 框架中,使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更加精细的控制,只控制一个对象的一个属性值,尔斯用多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的见习时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU的资源消耗。最重要的是,属性动画是通过调用get、set方法来真实的控制各View的属性值,基本可以实现所有的动画效果。所以View必须要提供setXxx方法,如果动画的时候没有传递初始值,那么还要提供getXxx方法,因为系统要去拿xxx属性的初始值(如果这条不满足,程序直接Crash) 。View的setXxx对属性xxx所做的改变必须能够通过某种方法反映出来,比如会带来ui的改变啥的(如果这条不满足,动画无效果但不会Crash)。
举一个最简单的例子:
这里写图片描述

    ObjectAnimator animator = ObjectAnimator.ofFloat(btn1, "translationX", 0, 500); 
    animator.setDuration(3000);
    animator.start();

  ObjectAnimator.ofFloat(btn1, “translationX”, 0, 500); 这里第一个参数是要操纵的view,我的是一个button,第二个参数是要操纵的属性,最后一个参数是一个可变数组参数,传入属性变化的取值过程。和视图动画一样可以设置动画时长等属性。

常见的属性值:translationX、translationY:view对象从他布局容器的左上角坐标偏移的位置
       rotation、rotationX、rotationY:控制view围绕支点进行2D、3D的旋转
       scaleX、scaleY:控制view对象围绕支点进行2D缩放
       pivotX、pivotY:view对象的支点位置,围绕这个支点旋转缩放,默认为view对象的中心店
       x、y:view在容器中的位置
       alpha:view的透明度
       
  ObjectAnimator.ofFloat使用时要注意属性的数据类型,比如translationX属性使用了ObjectAnimator.ofInt(….)方法时,就会被认为报Method setTranslationX() with type int not found on target class 错误;同样一个属性没有对应get、set方法时,属性动画是不是就没办法了呢?答案肯定是否定的。可以通过一个自定义属性类或者包装类来间接的给这个属性增加get、set方法。
例如:

private static class ViewWrapper {
        private View mTarget;

        public ViewWrapper(View target) {
            mTarget = target;
        }

        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }

        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    }

这样就给属性包装了一层,使用时只要操纵包装类即可:

        ViewWrapper wrapper = new ViewWrapper(mButton);
        ObjectAnimator.ofInt(wrapper, width, 500).setDuration(5000).start();

这里写图片描述

PropertyValuesHolder

  在视图动画中用AnimationSet可以实现多个动画一起执行,在属性动画中,针对一个对象的多个属性进行操控,完成类似AnimationSet的效果可以通过PropertyValuesHolder来实现。
例如:

        PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f); 
        PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
        PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("translationX",0, 500);
        ObjectAnimator.ofPropertyValuesHolder(view,pvh1,pvh2,pvh3).setDuration(3000).start();

这里写图片描述

ValueAnimator

   ValueAnimator在属性动画中占非常重要的地位。他本身不提供任何动画效果,它更像一个数值发生器,用来产生一定规律的数字,从而让调动着来控制动画的实践过程。ValueAnimator的一般使用方法如下所示,通常情况下,在ValueAnimator的AnimatorUpdateListenerListener中监听数值的变化,从而完成动画的变换。

        ValueAnimator animator = ValueAnimator.ofFloat(0,100);
        animator.setTarget(view);
        animator.setDuration(1000).start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value = (Float)animation.getAnimatedValue();
                //use the value
            }
        });

动画的监听

一个完整的动画有Start、Repat、End、Cancel四个过程,通过Android提供了接口,可以很方便的监听这四个事件:

 animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) { 
            }
            @Override
            public void onAnimationEnd(Animator animation) {
            }
            @Override
            public void onAnimationCancel(Animator animation) {
            }
            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });

   大部分时候只关心onAnimationEnd事件,所以Android也提供了一个animatorListenerAdapter来让我们选择必要时间进行监听:

animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
    }
});

AnimatorSet

   对于一个属性同时作用多个属性动画效果,可以用PropertyValuesHolder实现,但是用AnimatorSet不仅能实现这样的效果还可以更加精确的顺序控制。

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX",500f); 
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX",1f,0f,1f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY",1f,0f,1f);
        AnimatorSetset = new AnimatorSet();
        set.setDuration(2000);
        set.playSequentially(animator1,animator2,animator3);
        set.start();

这里写图片描述

  在属性动画中AnimatorSet正是通过playTogether()、playSequentially()、animSet.play().with()、before()、after()这些方法来控制多个动画协同工作,从而做到对动画播放顺序的精确控制。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值