关于动画估值器的那些事!!!

前几天的博客中,一直在说视图动画和属性动画,当然除了这些之外,也稍微介绍来了一下关于动画插值器的相关内容,但是插值器跟估值器是有很大的不同的!!!不信?那就继续往下看吧!!!首先借用前几篇博客中的例子,我们来看一下插值器是如何工作的!
还是使用ScaleAnimation动画,这里只给出主要源码,详细源码有兴趣的可以自己看一下!!!
ScaleAnimation.java

protected void applyTransformation(float interpolatedTime, Transformation t) {
        float sx = 1.0f;
        float sy = 1.0f;
        float scale = getScaleFactor();

        if (mFromX != 1.0f || mToX != 1.0f) {
            sx = mFromX + ((mToX - mFromX) * interpolatedTime);
        }
        if (mFromY != 1.0f || mToY != 1.0f) {
            sy = mFromY + ((mToY - mFromY) * interpolatedTime);
        }

        if (mPivotX == 0 && mPivotY == 0) {
            t.getMatrix().setScale(sx, sy);
        } else {
            t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
        }
    }

看一个最简单的插值器,线性插值器:
LinearInterpolator.java:

LinearInterpolator
    public float getInterpolation(float input) {
        return input;
    }

其中在ScaleAnimation的代码中,interpolatorTime的值就是插值器中getInterpolation方法的返回值,动画根据插值器的返回值对Scale属性进行处理,是不是感觉很相似!!!
在源码中通过一些简单的计算,计算出sx和sy的值,这里的值不就是代表动画的水平和垂直方向的缩放倍数吗,最后通过矩阵实现。

这里的计算在属性动画中就是通过估值器实现,估值器就是根据插值器返回的动画进度,计算出当前动画的value值,并通过相应的属性设置方法进行设置,或者通过接口进行返回,如果你还不信的话,我们就看一下,FloatEvalutor的实现方法!!!

    public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }

看到了吗?是不是感觉很简单,跟上面ScaleAnimation中的计算过程是不是一模一样!!!相信看到这里你也就明白估值器在属性动画中的作用了吧(别跟我说你还不清楚呀)!!

是不是感觉估值器很简单,OK,我们现在来自定义一个估值器,只属于我们自己的估值器,嗯,就真的只是自己的!!!

在使用自定义估值器的时候,需要View的属性具有get和set方法,而且在使用估值器的时候,最需要关注的就是估值器返回值的类型,这个类型必须与view属性值得类型相同,不然应该会抛出异常!!!

先看一下效果图吧:
这里写图片描述这里写图片描述这里写图片描述

看一下主布局文件吧:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.evalutordemo.MainActivity">

    <com.example.evalutordemo.CustomTextView
        android:id="@+id/tv"
        android:layout_width="200dp"
        android:layout_height="40dp"
         />
    <Button
        android:text="@string/start_animator"
        android:textAllCaps="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv"
        android:onClick="startAnimator"/>
</RelativeLayout>

自定义View文件:

package com.example.evalutordemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

/**
 * Created by Administrator on 2017/3/25 0025.
 */

public class CustomTextView extends View {
    private Character mText = '*';
    private Paint p;
    private Rect text;
    private Rect canvasRect;
    public CustomTextView(Context context) {
        this(context,null);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        p = new Paint();
        p.setColor(Color.RED);
        p.setTextSize(48);
        p.setTextAlign(Paint.Align.LEFT);
        text = new Rect();
        canvasRect = new Rect();
    }


    public Character getText1(){
        char value = mText;
        return new Character(value);
    }
    public void setText1(Character c){
        mText = c;
        invalidate();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        canvasRect.left = getPaddingLeft();
        canvasRect.top = getPaddingTop();
        canvasRect.right = getWidth()-getPaddingRight();
        canvasRect.bottom = getHeight()-getPaddingBottom();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        p.setColor(Color.RED);
        p.getTextBounds(mText.toString(),0,mText.toString().length(),text);
        canvas.drawRect(canvasRect,p);
        p.setColor(Color.BLACK);
        canvas.drawText(mText.toString(),(canvasRect.width()-text.width())/2+getPaddingLeft(),canvasRect.bottom-(canvasRect.height()-text.height())/2,p);
    }
}

Activity文件:

package com.example.evalutordemo;

import android.animation.FloatEvaluator;
import android.animation.IntEvaluator;
import android.animation.ValueAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private ValueAnimator valueAnimator;
    private CustomTextView tv;
    private IntEvaluator intEvaluator;
    private FloatEvaluator floatEvaluator;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (CustomTextView)findViewById(R.id.tv);
        valueAnimator = new ValueAnimator();
        valueAnimator.setObjectValues(new Character('A'),new Character('Z'));
        valueAnimator.setEvaluator(new CharEvalutor());
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setTarget(tv);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                char value = (char) animation.getAnimatedValue();
                tv.setText1(value);
            }
        });
        valueAnimator.setDuration(25000);
    }

    public void startAnimator(View view){
        valueAnimator.start();
    }
}

在自定义View中我们设置了一个 mText 属性,类型为Character,所以我们在自定义Evalutor的时候,里面的类型也需要设置为Character。还是看一下代码吧:

package com.example.evalutordemo;

import android.animation.TypeEvaluator;
import android.text.style.CharacterStyle;

/**
 * Created by Administrator on 2017/3/25 0025.
 */

public class CharEvalutor implements TypeEvaluator<Character> {
    @Override
    public Character evaluate(float fraction, Character startValue, Character endValue) {
        char value = (char) (startValue+(endValue-startValue)*fraction);
        return value;
    }
}

看到这个自定义估值器是不是感觉很简单,估值器虽然存在差异,但是差异应该是不会很大的,好了,关于插值器的内容就介绍到这里吧,以后遇到新的内容在进行补充吧!!

这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!

公众号

代码地址:
https://github.com/zhuyuqiang2017/Animation

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值