美文网首页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