@coder-pig 2015-11-18T08:36:23.000000Z 字数 8394 阅读 1455

# Android基础入门教程——8.4.4 Android动画合集之属性动画-又见

Android基础入门教程

## 本节引言：

Android属性动画完全解析(上)，初识属性动画的基本用法
Android属性动画完全解析(中)，ValueAnimator和ObjectAnimator的高级用法
Android属性动画完全解析(下)，Interpolator和ViewPropertyAnimator的用法

## 1.Evaluator自定义

### 1）Evaluator介绍

• fraction：动画的完成度，我们根据他来计算动画的值应该是多少
• startValue：动画的起始值
• endValue：动画的结束值

### 2）使用示例

/** * Created by Jay on 2015/11/18 0018. */public class Point {    private float x;    private float y;    public Point() {    }    public Point(float x, float y) {        this.x = x;        this.y = y;    }    public float getX() {        return x;    }    public float getY() {        return y;    }    public void setX(float x) {        this.x = x;    }    public void setY(float y) {        this.y = y;    }}

/** * Created by Jay on 2015/11/18 0018. */public class PointEvaluator implements TypeEvaluator<Point>{    @Override    public Point evaluate(float fraction, Point startValue, Point endValue) {        float x = startValue.getX() + fraction * (endValue.getX() - startValue.getX());        float y = startValue.getY() + fraction * (endValue.getY() - startValue.getY());        Point point = new Point(x, y);        return point;    }}

/** * Created by Jay on 2015/11/18 0018. */public class AnimView extends View {    public static final float RADIUS = 80.0f;    private Point currentPoint;    private Paint mPaint;    public AnimView(Context context) {        this(context, null);    }    public AnimView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public AnimView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    private void init() {        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(Color.BLUE);    }    private void drawCircle(Canvas canvas){        float x = currentPoint.getX();        float y = currentPoint.getY();        canvas.drawCircle(x, y, RADIUS, mPaint);    }    private void startAnimation() {        Point startPoint = new Point(RADIUS, RADIUS);        Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);        ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                currentPoint = (Point) animation.getAnimatedValue();                invalidate();            }        });        anim.setDuration(3000l);        anim.start();    }    @Override    protected void onDraw(Canvas canvas) {        if (currentPoint == null) {            currentPoint = new Point(RADIUS, RADIUS);            drawCircle(canvas);            startAnimation();        } else {            drawCircle(canvas);        }    }}

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new AnimView(this));    }}

### 3)示例增强版

int color来控制颜色，另外写上getColor()和setColor()的方法，我们先来自定义个Evaluator吧~

ColorEvaluator.java

/** * Created by Jay on 2015/11/18 0018. */public class ColorEvaluator implements TypeEvaluator<Integer>{    @Override    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {        int alpha = (int) (Color.alpha(startValue) + fraction *                (Color.alpha(endValue) - Color.alpha(startValue)));        int red = (int) (Color.red(startValue) + fraction *                (Color.red(endValue) - Color.red(startValue)));        int green = (int) (Color.green(startValue) + fraction *                (Color.green(endValue) - Color.green(startValue)));        int blue = (int) (Color.blue(startValue) + fraction *                (Color.blue(endValue) - Color.blue(startValue)));        return Color.argb(alpha, red, green, blue);    }}

AnimView2.java

/** * Created by Jay on 2015/11/18 0018. */public class AnimView2 extends View {    public static final float RADIUS = 80.0f;    private Point currentPoint;    private Paint mPaint;    private int mColor;    public AnimView2(Context context) {        this(context, null);    }    public AnimView2(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public AnimView2(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    private void init() {        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(Color.BLUE);    }    private void drawCircle(Canvas canvas){        float x = currentPoint.getX();        float y = currentPoint.getY();        canvas.drawCircle(x, y, RADIUS, mPaint);    }    private void startAnimation() {        Point startPoint = new Point(RADIUS, RADIUS);        Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);        ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                currentPoint = (Point) animation.getAnimatedValue();                invalidate();            }        });        ObjectAnimator objectAnimator = ObjectAnimator.ofObject(this, "color", new ColorEvaluator(),                Color.BLUE, Color.RED);        //动画集合将前面两个动画加到一起，with同时播放        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.play(anim).with(objectAnimator);        animatorSet.setStartDelay(1000l);        animatorSet.setDuration(3000l);        animatorSet.start();    }    @Override    protected void onDraw(Canvas canvas) {        if (currentPoint == null) {            currentPoint = new Point(RADIUS, RADIUS);            drawCircle(canvas);            startAnimation();        } else {            drawCircle(canvas);        }    }    //color的get和set方法~    public int getColor() {        return mColor;    }    public void setColor(int color) {        mColor = color;        mPaint.setColor(color);        invalidate();    }}

## 2.Interpolator(补间器)

animatorSet.setInterpolator(new AccelerateInterpolator(2f));

### 1）Interpolator的内部实现机制

getInterpolation()方法中接收一个input参数，这个参数的值会随着动画的运行而不断变化，

input的值是由系统经过计算后传入到getInterpolation()方法中的，然后我们可以自己实现
getInterpolation()方法中的算法，根据input的值来计算出一个返回值，而这个返回值就是fraction了。

Interpolator的实现方式！其实无非就是算法不同，这就涉及到一些数学的东西了，又一次

(float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f 的算法理解：

### 2）自定义Interpolator

>

    private class DecelerateAccelerateInterpolator implements TimeInterpolator {        @Override        public float getInterpolation(float input) {            if (input < 0.5) {                return (float) (Math.sin(input * Math.PI) / 2);            } else {                return 1 - (float) (Math.sin(input * Math.PI) / 2);            }        }    }

## 3.ViewPropertyAnimator

3.1后系统当中附增的一个新的功能，为View的动画操作提供一种更加便捷的用法！

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 0f);  animator.start(); 

textview.animate().alpha(0f);  

textview.animate().x(500).y(500).setDuration(5000)          .setInterpolator(new BounceInterpolator());  

• 整个ViewPropertyAnimator的功能都是建立在View类新增的animate()方法之上的，
这个方法会创建并返回一个ViewPropertyAnimator的实例，之后的调用的所有方法，
设置的所有属性都是通过这个实例完成的。
• 使用ViewPropertyAnimator将动画定义完成之后，动画就会自动启动
并且这个机制对于组合动画也同样有效，只要我们不断地连缀新的方法，
那么动画就不会立刻执行，等到所有在ViewPropertyAnimator上设置的方法都执行完毕后，
动画就会自动启动。当然如果不想使用这一默认机制的话，我们也可以显式地调用
start()方法来启动动画。
• ViewPropertyAnimator的所有接口都是使用连缀的语法来设计的，每个方法的返回值都是
自身的实例，因此调用完一个方法之后可以直接连缀调用它的另一个方法，这样把所有的
功能都串接起来，我们甚至可以仅通过一行代码就完成任意复杂度的动画功能。

## 4.本节示例代码下载

AnimatorDemo3.zip

## 本节小结

ViewPropertyAnimator，是不是又拓展了大家的见识~本节也是Android基础入门绘图

PS:后面的示意图换模拟器是因为的N5秀逗了...

• 私有
• 公开
• 删除