Android 动画之属性动画(三)

来源:互联网 发布:java ping 编辑:程序博客网 时间:2024/06/03 22:49

Android动画系列:

  1. Android之补间动画详解
  2. Android 动画之帧动画
  3. Android 动画之LayoutAnimation
  4. Android 动画之属性动画(一)
  5. Android 动画之属性动画(二)
  6. Android 动画之属性动画(三)
  7. Android 动画之属性动画(四)
  8. Android 动画之LayoutTransition
  9. Android 动画之AnimatorSet

这里写图片描述
对于Evaluators,即属性动画计算器,官方根据实际需求已经为我们实现了几种,但在实际开发过程中,官方定义的那几种并不能满足我们实际的需求,比如在背景变色的同时将控件移动并缩小,有的人说可以使用AnimatorSet实现,当然能AnimatorSet可以轻易实现,假如我们就用一个ValueAnimator该怎么实现呢?

之前有提到过TypeEvaluator这个接口,其用来实现自定义动画属性值的计算器。TypeEvaluator接口中只定义了一个方法,evaluate(float fraction, T startValue, T endValue),evaluate可以接受三个参数fraction,startValue,endValue,其中startValue和endValue都是使用泛型定义的,意味着我们可以自定义传入的计算的动画属性,其返回值也使我们定义的的动画属性类型,以达到在AnimatorUpdateListener监听中,计算出来的属性值都是我们定义的。

TypeEvaluator的实现类一般与 setEvaluator(TypeEvaluator)方法或者ofObject(TypeEvaluator, Object… values)配合使用,来定义动画的属性值计算器。

  • fraction : 动画进度
  • startValue T : 动画属性初始值
  • endValue T: 动画属性结束值

自定义TypeEvaluator

首先,定一个动画相关属性的类MyPoint,其内包含了trance、color、scale等三个动画相关的属性。

public class MyPoint {    float trance; // 移动距离    int color; // 颜色    float scale; // 缩放比例    ****}

接下来,我们自定义一个Evaluator类,命名为MyEvaluator,其实现了接口TypeEvaluator,并将刚才定义的MyPoint作为动画的属性值类型。在evaluate()方法中,根据动画的执行进度,对trance、color、scale等三个属性分别做了相应处理。

public class MyEvaluator implements TypeEvaluator<MyPoint> {    @Override    public MyPoint evaluate(float fraction, MyPoint pointStart, MyPoint pointEnd) {        MyPoint pointCurrent = new MyPoint();        pointCurrent.setColor(getCurrentColor(fraction, pointStart.getColor(), pointEnd.getColor()));        pointCurrent.setTrance(getCurrentTrance(fraction, pointStart.getTrance(), pointEnd.getTrance()));        pointCurrent.setScale(getCurrentScale(fraction, pointStart.getScale(), pointEnd.getScale()));        return pointCurrent;    }    /**     * 根据fraction值来计算当前的颜色。     */    private int getCurrentColor(float fraction, int startColor, int endColor) {        int redCurrent;        int blueCurrent;        int greenCurrent;        int alphaCurrent;        int redStart = Color.red(startColor);        int blueStart = Color.blue(startColor);        int greenStart = Color.green(startColor);        int alphaStart = Color.alpha(startColor);        int redEnd = Color.red(endColor);        int blueEnd = Color.blue(endColor);        int greenEnd = Color.green(endColor);        int alphaEnd = Color.alpha(endColor);        int redDifference = redEnd - redStart;        int blueDifference = blueEnd - blueStart;        int greenDifference = greenEnd - greenStart;        int alphaDifference = alphaEnd - alphaStart;        redCurrent = (int) (redStart + fraction * redDifference);        blueCurrent = (int) (blueStart + fraction * blueDifference);        greenCurrent = (int) (greenStart + fraction * greenDifference);        alphaCurrent = (int) (alphaStart + fraction * alphaDifference);        return Color.argb(alphaCurrent, redCurrent, greenCurrent, blueCurrent);    }    /**     * 根据fraction值来计算当前的移动距离     */    private float getCurrentTrance(float fraction, float tranceStart, float tranceEnd) {        float tranceCurrent;        float difference;        difference = tranceEnd - tranceStart;        tranceCurrent = tranceStart + difference * fraction;        return tranceCurrent;    }    /**     * 根据fraction值来计算当前缩放比例     */    private float getCurrentScale(float fraction, float scaleStart, float scaleEnd) {        float scaleCurrent;        float difference;        difference = scaleEnd - scaleStart;        scaleCurrent = scaleStart + difference * fraction;        return scaleCurrent;    }}

最后使用静态方法ofObject(TypeEvaluator, T…values)创建ValueAnimator对象valueAnimator,通过系列setXX()方法,对valueAnimator做动画的相应设置,在AnimatorUpdateListener监听的onAnimationUpdate(ValueAnimator)方法中,通过getAnimatedValue()可以获得当前的动画的属性值,其类型强转为MyPoint,再设定View的相关属性,以达到动画效果。

//起始颜色为红色int startColor = 0xffff0000;//终止颜色为绿色int endColor = 0xff00ff00;MyPoint pointStart = new MyPoint(0f, startColor, 1.0f);MyPoint pointEnd = new MyPoint(400f, endColor, 0.2f);// 通过静态方法构建一个ValueAnimator对象// 动画属性值计算器使用自定义的计算器(MyEvaluator)ValueAnimator valueAnimator = ValueAnimator.ofObject(new MyEvaluator(), pointStart, pointEnd);// 设置作用对象valueAnimator.setTarget(btnProperty);// 设置动画无限循环valueAnimator.setRepeatCount(ValueAnimator.INFINITE);// 设置动画执行时间valueAnimator.setDuration(4000);// 添加动画更新监听valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        // 获取当前值        MyPoint mValue = (MyPoint) animation.getAnimatedValue();        // 动画进度(t/duration)        float fraction = animation.getAnimatedFraction();        Log.d("PropertyActivity", "mValue:" + mValue.toString());        Log.d("PropertyActivity", "fraction:" + fraction + " | t:" + fraction * animation.getDuration());        // 设置横向偏移量        btnProperty.setTranslationX(mValue.getTrance() * 0.5f);        // 设置纵向偏移量        btnProperty.setTranslationY(mValue.getTrance());        // 设置背景颜色        btnProperty.setBackgroundColor(mValue.getColor());        // 设置横向缩放        btnProperty.setScaleX(mValue.getScale());        // 设置纵向缩放        btnProperty.setScaleX(mValue.getScale());    }});valueAnimator.start();

这里写图片描述

0 0
原创粉丝点击