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

来源:互联网 发布:多媒体课件制作软件 编辑:程序博客网 时间:2024/06/01 11:55

前几天的博客中,一直在说视图动画和属性动画,当然除了这些之外,也稍微介绍来了一下关于动画插值器的相关内容,但是插值器跟估值器是有很大的不同的!!!不信?那就继续往下看吧!!!首先借用前几篇博客中的例子,我们来看一下插值器是如何工作的!
还是使用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
原创粉丝点击