属性动画Property Animation的扩展用法

Interpolator的使用


Interpolator字面意思就是插入器(有道翻译),在动画中,它的主要作用是改变动画的执行速率,比如匀速,加速等一系列效果。Interpolator可以自定义实现,以下是Android系统已经为我们写好了的一些插入器:

  • AccelerateDecelerateInterpolator   ------ 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
  • AccelerateInterpolator    -------------------  在动画开始的地方速率改变比较慢,然后开始加速
  • AnticipateInterpolator   --------------------- 开始的时候向后然后向前甩
  • AnticipateOvershootInterpolator  -------- 开始的时候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator   ------------------------ 动画结束的时候弹起,类似皮球掉地上弹起的效果
  • CycleInterpolator  ---------------------------  动画循环播放特定的次数,速率改变沿着正弦曲线
  • DecelerateInterpolator ---------------------  在动画开始的地方快然后慢
  • LinearInterpolator   -------------------------  以常量速率改变,即匀速
  • OvershootInterpolator    -------------------  向前甩一定值后再回到原来位置

具体的使用比较简单,在Java代码中调用动画对象的setInterpolator()方法传入Interpolator对象:
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mImageView, "translationY", mImageView.getTranslationY(),
                400);
        // 设置动画时长
        objectAnimator.setDuration(5000);
        // 设置弹起效果
        objectAnimator.setInterpolator(new BounceInterpolator());
        objectAnimator.start();
在xml中使用android:interpolator 属性:
<?xml version="1.0" encoding="utf-8"?>
<!-- 将alpha的值从1过渡到0,时长1秒 -->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"
    android:duration="1000"
    android:propertyName="alpha"
    android:interpolator="@android:anim/linear_interpolator"/>

TypeEvaluator的用法


TypeEvaluator翻译为类型估值算法,又称估值器,它的作用是通过起始值、结束值以及插值器返回值来计算在该时间点的属性值应该是多少,也就是控制动画实际运动轨迹,系统给我们提供IntEvaluator(针对整型属性)、FloatEvaluator(针对浮点型属性)以及ArgbEvaluator(针对Color属性),如果想根据某个属性TYPE来实现动画,但是这个Type又不是Android系统内置的,这个时候就需要创建一个自己的evaluator来实现了,并且新创建的type必须实现接口TypeEvaluator。Android系统内置的type有int,float和color,他们对应的evaluator是IntEvaluator、FloatEvaluator和ArgbEvaluator。接口TypeEvaluator内只有一个方法,用来计算要实现动画属性的值。以下是TypeEvaluator接口:
/**
 * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators
 * allow developers to create animations on arbitrary property types, by allowing them to supply
 * custom evaluators for types that are not automatically understood and used by the animation
 * system.
 *
 * @see ValueAnimator#setEvaluator(TypeEvaluator)
 */
public interface TypeEvaluator<T> {

    /**
     * This function returns the result of linearly interpolating the start and end values, with
     * <code>fraction</code> representing the proportion between the start and end values. The
     * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
     * and <code>t</code> is <code>fraction</code>.
     *
     * @param fraction   The fraction from the starting to the ending values
     * @param startValue The start value.
     * @param endValue   The end value.
     * @return A linear interpolation between the start and end values, given the
     *         <code>fraction</code> parameter.
     */
    public T evaluate(float fraction, T startValue, T endValue);

}
接口只有一个方法evaluate()返回了一个泛型,方法的第一个参数是估值小数,也就是插值器计算出来的当前属性改变的百分比,第二个参数是动画开始值,第三个参数是动画的结束值。
我们看看IntEvaluator的实现:
/**
 * This evaluator can be used to perform type interpolation between <code>int</code> values.
 */
public class IntEvaluator implements TypeEvaluator<Integer> {

    /**
     * This function returns the result of linearly interpolating the start and end values, with
     * <code>fraction</code> representing the proportion between the start and end values. The
     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
     * and <code>t</code> is <code>fraction</code>.
     *
     * @param fraction   The fraction from the starting to the ending values
     * @param startValue The start value; should be of type <code>int</code> or
     *                   <code>Integer</code>
     * @param endValue   The end value; should be of type <code>int</code> or <code>Integer</code>
     * @return A linear interpolation between the start and end values, given the
     *         <code>fraction</code> parameter.
     */
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }
}
很明显,其在evaluate()方法中进行了数值的转换,并返回了结果,所以我们只需照着做就行。
比如,我现在需要让一个图片实现抛物线运动,则可以借助自定义的TypeEvaluator实现,首先定义一个坐标类Point,里面包含x轴跟y轴,以及对应的setter,getter
/**
 * 坐标点,用于控制动画的位置
 * Created by zhangyongming on 2017/1/11.
 */

public class Point {
    private float x;
    private float y;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }
}
然后是自定义的PointEvaluator类,这里我们获取动画执行时的x轴跟y轴的坐标,并返回一个Point对象。
/**
 * Point的估值器
 * Created by zhangyongming on 2017/1/11.
 */

public class PointEvaluator implements TypeEvaluator<Point> {
    @Override
    public Point evaluate(float fraction, Point startValue, Point endValue) {
        float resultX = startValue.getX() + (endValue.getX() - startValue.getX()) * fraction;
        float resultY = startValue.getY() + (endValue.getY() - startValue.getY()) * fraction;
        return new Point(resultX,resultY);
    }
}
接下来就是给ImageView使用了:
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointEvaluator(), new Point(50, 50), new Point(500,
                500));
        valueAnimator.setDuration(2000);
        valueAnimator.start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                Point point = (Point) valueAnimator.getAnimatedValue();
                mImageView.setX(point.getX());
                mImageView.setY(point.getY());
            }
        });

基本上的实现思路就是这样的。

PropertyValuesHolder的用法


propertyValuesHolder可以用于动画的组合执行,使用起来很简单,如下示例:
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
        ObjectAnimator.ofPropertyValuesHolder(mImageView, alpha, scaleX, scaleY).setDuration(2000).start();
这样就能很容易地实现三个动画的组合播放了。

ViewPropertyAnimator的用法


ViewPropertyAnimator可以用一种很简便的方式让控件执行动画,该 类提供了链式调用进行多个属性同时变化的动画,更加简洁方便我们操作组合动画(多个属性同时进行变化),它可以为同时动画提供更好的性能。ViewPropertyAnimator在动画进行的时候只对多个属性的变化进行一次invalidate调用,而不是对变化每个属性进行调用(n个ObjectAnimator就会进行n次属性变化,就有n次invalidate)。当然这个类的调用方式更方便,调用对应属性方法传一个属性值就可以自动实现动画。每个属性方法都有两种调用形式,例如 alpha(float value) 和alphaBy(float value),前者是变化到多少,后者是变化多少。
ViewPropertyAnimator没用提供公开的构造方法,通过调用view的animate()获取引用。

总而言之:
  • ViewPropertyAnimator操作View对象的。
  • 提供链式调用设置多个属性动画,这些动画同时进行的。
  • 更好的性能,多个属性动画是一次同时变化,只执行一次UI刷新。
  • 每个属性提供两种类型方法设置。
  • ViewPropertyAnimator只能通过View的animate()获取引用进行设置。
比如让一个图片控件由透明变为不透明
        mImageView.animate().alpha(0f).setDuration(1000);
是不是很方便?当然也可以使用插入器,同样只需要在后面继续调用setInterpolator()方法即可
        mImageView.animate().alpha(0f).setDuration(1000).setInterpolator(new LinearInterpolator());
只需要使用连缀的方式使用就行,大大简化了代码,如果需要实现组合动画也一样,同样使用连缀的方式
        mImageView.animate().alpha(0f).rotation(360).setDuration(1000).setInterpolator(new LinearInterpolator());
可以看出我们不需要调用start()方法,这是由于ViewPropertyAnimator在将我们所有的连缀的方法初始化之后会为我们调用start()方法,使动画执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值