插值器和估值器的介绍

1. 插值器

插值器是在 XML 中定义的动画修改器,它会 影响动画的变化速率。插值器可对现有的动画效果执行加速、减速、重复、退回等

插值器通过 android:interpolator 属性应用于动画元素,该属性的值是对插值器资源的引用

Android默认提供了9个插值器供使用:

  1. AccelerateDecelerateInterpolator:变化率在开始和结束时缓慢,但在中间会加快
  2. AccelerateInterpolator:变化率在开始时较为缓慢,然后会加快
  3. AnticipateInterpolator:先反向变化,然后再急速正向变化
  4. AnticipateOvershootInterpolator:先反向变化,再急速正向变化并超过目标值,然后以最终值结束
  5. BounceInterpolator:变化会在结束时退回
  6. CycleInterpolator:按指定的循环次数重复动画。变化率符合正弦曲线图
  7. DecelerateInterpolator:变化率开始时很快,然后减慢
  8. LinearInterpolator:变化率恒定不变
  9. OvershootInterpolator:先急速正向变化,再超过最终值,然后回到最终值
  10. TimeInterpolator:该接口用于实现自定义的插值器

原理说明:

public interface TimeInterpolator{
    float getInterpolator(float input);
}

当前动画开始后,View会周期性调用它的getTransformation方法不断获得动画结果,方法返回表示的是当前动画是否结束

// Animation.java
public boolean getTransformation(long currentTime, Transformation outTransformation){
    //...
     if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
         //...
         // 插值器
         final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
         // 子类完成实际的动画逻辑
         applyTransformation(interpolatedTime, outTransformation);
     }
}

Transformation:包含Matrix和Alpha字段,用来记录某次动画计算的变换结果

// ViewGroup.java
Transformation getChildTransformation() {
        if (mChildTransformation == null) {
            mChildTransformation = new Transformation();
        }
        return mChildTransformation;
    }

调用栈追溯

// View.java
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
    //...
    final Animation a = getAnimation();
    if (a != null) {
        more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
        //...
    }
}
private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
            Animation a, boolean scalingRequired) {
    //...
    final Transformation t = parent.getChildTransformation();
  	boolean more = a.getTransformation(drawingTime, t, 1f);
    //...
}
 

属性动画 ValueAnimator

// ValueAnimator.java
void animateValue(float fraction){
    // 插值器
    fraction = mInterpolator.getInterpolation(fraction);
    //...
}

2. 估值器

public interface TypeEvaluator<T> {
    public T evaluate(float fraction, T startValue, T endValue);
}

插值器 的返回值转换成我们需要的值,设置属性值从初始值过渡到结束值变化的具体数值,可以理解为运动轨迹的表现

public class PointView{
    public float x;
    public float y;
}

自定义一个TypeEvaluator

class PointViewEvaluator implements TypeEvaluator{
    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue){
        PointView pv = new PointView();
        pv.x = 400*(fraction*2);
        pv.y = 400*Math.pow(fraction*2,2);
    }
}

另外我们将时间写死了为2s。自定义好之后我们就可以直接拿过来用了代码如下

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView ivBall;
    private Button btnClick;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ivBall=findViewById(R.id.iv_ball);
        btnClick=findViewById(R.id.btn_click);
        btnClick.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        ValueAnimator valueAnimator=ValueAnimator.ofObject(new PointViewEvaluator(),new PointView(0,0));
        valueAnimator.setDuration(2000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //获取ValueAnimator在运动时,当前运动点的值
                PointView pointView= (PointView) valueAnimator.getAnimatedValue();
                ivBall.setX(pointView.x);
                ivBall.setY(pointView.y);
            }
        });
        valueAnimator.start();
    }
}

运行之后可发现,上述动画轨迹是匀速执行的抛物线运动。通过以上例子我们可以感受估值器的作用是什么样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值