美文网首页andnroid
android属性动画

android属性动画

作者: L_Xian | 来源:发表于2016-05-27 17:45 被阅读325次

    属性动画中最基础的 ObjectAnimator

    ObjectAnimator 是属性动画中最重要的实行类,创建一个ObjectAnimator只需要通过他的静态工厂方类直接返回一个ObjectAnimator对象。参数包括一个对象和对象的属性名字,但这个属性必须有getset函数,内部会通过反射机制来调用set函数修改对象属性值,也可以调用setInterpolator设置对应的差值器。

    属性动画操作的是属性,所以被操作的view可以响应事件。

    例子:实现平移动画

    ObjectAnimator animator = ObjectAnimator.ofFloat(
                    view,
                    "translationX",
                    300
            );
    animator.setDuration(300);
    animator.start();
    
    • 第一个参数是要操纵的View
    • 第二个参数是要操作的属性
    • 第三个是一个可变数组参数,需要穿进去该属性变化的一个取值过程,这里就是变化到300
    • 下面是给动画设置时长,差值器等属性

    注意到ofFloat方法,这是源码中的注释

    /**
     * Constructs and returns an ObjectAnimator that animates between float values. A single
     * value implies that that value is the one being animated to. Two values imply starting
     * and ending values. More than two values imply a starting value, values to animate through
     * along the way, and an ending value (these values will be distributed evenly across
     * the duration of the animation).
     *
     * @param target The object whose property is to be animated. This object should
     * have a public method on it called <code>setName()</code>, where <code>name</code> is
     * the value of the <code>propertyName</code> parameter.
     * @param propertyName The name of the property being animated.
     * @param values A set of values that the animation will animate between over time.
     * @return An ObjectAnimator object that is set up to animate between the given values.
     */
    

    大概意思是:

    /**
     * 构造并返回一个浮点值之间的动画ObjectAnimator。单
     * 值意味着该值被动画的之一。两个值意味着启动
     * 和结束值。多于两个值意味着一个起始值,值动画通过
     * 一路走来,和结束值(这些值将均匀分布在整个
     * 动画的持续时间)。
     *
     * @参数target其属性是动画的对象。这个对象应该
     * 有它的公共方法叫做<代码>的setName()</代码>,其中<代码>名称</ code>的是
     * 在<code>的值propertyname</ code>的参数。
     * @参数PROPERTYNAME被动画的属性的名称。
     * @参数值一组动画将随着时间的推移之间的动画值。
     * 返回:已设置给定的值之间设置动画的ObjectAnimator对象。
     */
    

    在使用ObjectAnimator的时候要注意的就是属性必须有getset方法,否则ObjectAnimator就无法生效。下面是常用的可以直接使用属性动画的属性值:

    • translationXtranslationY:这两个属性作为一种增量来控制着View对象从它布局容器左上角坐标偏移的位置。
    • rotation,rotationX,rotationY:这三个属性控制View对象围绕支点进行2D和3D旋转。
    • scaleX,scaleY:这两个属性控制View对象围绕它的支点进行2D缩放。
    • pivotX,pivotY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,支点是View对象的中心点。
    • xy:这是两个简单实用的属性,它描述了View对象在它容器中的最终位置,它是最初左上角坐标和translationX、translationY值的累计和。
    • alpha:它表示View对象的alpha透明度。默认是1(不透明),0代表完全透明(不可见)

    如果一个属性没有有getset方法,有两种解决方法。

    1. 通过自定义一个属性类或包装类来间接给这个属性添加get、set方法。
    2. 通过ValueAnimator实现

    第一种,通过自定义一个属性类或包装类来间接给这个属性添加get、set方法:

    WrapperView wrapper = new WrapperView(view);
    ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
    
    
    private static class WrapperView {
        private View mTarget;
    
        public WrapperView(View mTarget) {
            this.mTarget = mTarget;
        }
    
        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }
    
        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    }
    

    PropertyValuesHolder

    如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现,比如在平移中,同时改变X、Y轴的缩放,可以这样实现:

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

    ValueAnimator

    ValueAnimator本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字。从而让调用者控制动画的实现过程,ValueAnimator的一般使用方法如下:

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

    其中AnimatorUpdateListener监听数值的变换,从而完成动画的变换,这个例子中,value输出的是从0到100

    动画事件监听

    一个完整的动画监听包括四个过程:

    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
    anim.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事件,所以还可以这样通过AnimatorListenerAdapter选择想要的事件进行监听:

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

    AnimatorSet

    对于一个属性同时作用多个属性动画效果,除了使用PropertyValuesHolder外,还可以使用AnimatorSet,而且AnimatorSet还可以实现更为精确的顺序控制。

    ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
    ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0, 1f);
    ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0, 1f);
    AnimatorSet set = new AnimatorSet();
    set.setDuration(1000);
    set.playTogether(animator1, animator2, animator3);
    set.start();
    

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

    相关文章

      网友评论

        本文标题:android属性动画

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