Android-动画基础

属性动画-Property Animation

基本流程:

  1. 这个ValueAnimator对象会根据动画的总时间和已经流逝的时间计算出一个0到1之间的elapsed fraction值。这个elapsed fraction值就代表了时间完成的程度。
  2. 计算出elapsed fraction之后,ValueAnimator对象会调用TimeInterpolator 来计算一个interpolated fraction,即,根据所设置的时间插值方法将elapsed fraction映射到interpolated fraction。
      如果是线性插值的话elapsed fraction和interpolated fraction会是一直相等的,但是非线性变换就不是了。
  3. interpolated fraction计算出来后,ValueAnimator 会调用TypeEvaluator,来进行你要动画的属性值的计算。
      这时候用的输入参数就是interpolated fraction的值,以及属性值的起始值和终止值。

  整个过程如下图所示:
  这里写图片描述

View Anim 与 property Anim 的区别

View anim 系统

view animation system 提供的能力只能够为 View 添加动画。因此如果你想为非 View 对象添加动画,就必须自己去实现, view animation system 在 View 动画的展现方面也是有约束的,只暴露了 View 的很少方面。比如 View 支持缩放和旋转,但不支持背景颜色的动画。
view animation system 的另一劣势是,其改变的是 View 的绘制效果,真正的 View 的属性保持不变,比如无论你在对话中如何缩放 Button 的大小,Button 的有效点击区域还是没有应用到动画时的区域,其位置与大小都不变。
但是 View animation system 只需花费很少时间创建而且只需很少的代码。如果 View 动画完成了你所有的动作,或者你存在的代码已经达到了你想要的效果,就没必要使用 property 动画系统了。

property anim 系统

完全弥补了 View anim System 的缺陷,你可以为一个对象的任何属性添加动画,(View 或者非 View),同时对象自己也会被修改。 并且当属性变化的时候,property Anim 系统会自动的刷新屏幕。
属性动画系统在处理动画方面也更加强劲。更高级的,你可以指定动画的属性,比如颜色,位置,大小,定义动画的插值器并且同步多个动画。
并且在 Property Animation 中,改变的是对象的实际属性,如 Button 的缩放,Button 的位置与大小属性值都改变了。而且 Property Animation 不止可以应用于 View,还可以应用于任何对象。
平时使用的简单动画特效,使用 View 动画就可以满足,但是如果你想做的更加复杂,比如背景色的动画,或者不仅是 View,还希望对其它对象添加动画等,那么你就得考虑使用 Property 动画了。
更多动画开源库及使用,可以参考:Android 动画系列,其中介绍了一些基本使用,也提到了一些 GitHub 上的动画开源库,可以作为 Android 动画学习的资料

1.两个简单示例

1.1.ValueAnimator使用

 private static void testValueAnimator() {
        ValueAnimator animator=ValueAnimator.ofFloat(0,100);
        animator.setInterpolator(new LinearInterpolator());
        animator.setDuration(1000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float fraction = animation.getAnimatedFraction();//时间插值(线性插值器为0~1)
                float value = (float) animation.getAnimatedValue();//类型估值(0~100)
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        animator.start();
    }

1.2.AnimatorSet使用

private static void testAnimatorSet() {
        ValueAnimator animatorA=ValueAnimator.ofFloat(0,1);
        ValueAnimator animatorB=ValueAnimator.ofFloat(0,1);
        ValueAnimator animatorC=ValueAnimator.ofFloat(0,1);
        ValueAnimator animatorD=ValueAnimator.ofFloat(0,1);

        //A、B、C同时执行,D接着执行
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(animatorA).with(animatorB);
        animSet.play(animatorB).with(animatorC);
        animSet.play(animatorD).after(animatorC);
        animSet.setDuration(1000);
        animSet.start();
    }

2.Android自带时间插值器

Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。

2.1.Linear Interpolator / 线性插值器

类名: LinearInterpolator
资源ID: @android:anim/linear_interpolator
XML标记: linearInterpolator
公式: y=t
构造函数: public LinearInterpolator()
属性: 无

这里写图片描述

2.2.Accelerate Interpolator / 加速度插值器

类名: AccelerateInterpolator
资源ID: @android:anim/accelerate_interpolator
XML标记: accelerateInterpolator
公式: y=t^(2f)
构造函数: public AccelerateInterpolator(float factor)
参数:
名称: f
XML属性: android:factor
描述: 加速度参数. f越大,起始速度越慢,但是速度越来越快

![这里写图片描述](http://s3.51cto.com/wyfs02/M02/2F/4D/wKioL1OfBg7RSunbAAEfeaz5sDM514.jpg)

2.3.Decelerate Interpolator / 减速插值器

类名: DecelerateInterpolator
资源ID: @android:anim/decelerate_interpolator
XML标记: decelerateInterpolator
公式: y=1-(1-t)^(2f)
构造函数: public DecelerateInterpolator(float factor)
参数:
名称: f
XML属性: android:factor
描述: 加速度参数. f越大,起始速度越快,但是速度越来越慢

这里写图片描述

2.4.Accelerate Decelerate Interpolator / 先加速后减速插值器

类名: AccelerateDecelerateInterpolator
资源ID: @android:anim/accelerate_decelerate_interpolator
XML标记: accelerateDecelerateInterpolator
公式: y=cos((t+1)π)/2+0.5
构造函数: public AccelerateDecelerateInterpolator()
参数: 无

这里写图片描述

2.5.Anticipate Interpolator

类名: AnticipateInterpolator
资源ID: @android:anim/anticipate_interpolator
XML标记: anticipateInterpolator
公式: y=(T+1)×t^3–T×t^2
构造函数: public AnticipateInterpolator(float tension)
参数:
名称: T
XML属性: android:tension
描述: 张力值, 默认为2,T越大,初始的偏移越大,而且速度越快

这里写图片描述

2.6.Overshoot Interpolator

类名: OvershootInterpolator
资源ID: @android:anim/overshoot_interpolator
XML标记: overshootInterpolator
公式: y=(T+1)x(t1)^3+T×(t1)^2 +1
构造函数: public OvershootInterpolator (float tension)
参数:
名称: T
XML属性: android:tension
描述: 张力值,默认为2,T越大,结束时的偏移越大,而且速度越快

这里写图片描述

2.7.Anticipate Overshoot Interpolator

类名: AnticipateOvershootInterpolator
资源ID: @android:anim/anticipate_overshoot_interpolator
XML标记: anticipateOvershootInterpolator
公式:
这里写图片描述
构造函数:
public AnticipateOvershootInterpolator(float tension)
public AnticipateOvershootInterpolator(float tension, float extraTension)
参数:
XML属性: android:tension
描述: 张力值,默认为2,张力越大,起始和结束时的偏移越大,而且速度越快
XML属性: android:extraTension
描述: 额外张力值,默认为1.5。公式中T的值为tension*extraTension

这里写图片描述

2.8.Bounce Interpolator / 弹跳插值器

类名: BounceInterpolator
资源ID: @android:anim/bounce_interpolator
XML标记: bounceInterpolator
公式:
这里写图片描述
构造函数: public BounceInterpolator ()
参数: 无

这里写图片描述

2.9.Cycle Interpolator / 周期插值器

类名: CycleInterpolator
资源ID: @android:anim/cycle_interpolator
XML标记: cycleInterpolator
公式: y=sin(2π×C×t)
构造函数: public CycleInterpolator(float cycles)
参数:
名称: C
XML属性: android:cycles
描述: 周期值,默认为1;2表示动画会执行两次

这里写图片描述

自定义Interpolator与TypeEvaluator

1.思路:

  1. 自定义Interpolator需要重写getInterpolation(float input),控制时间参数的变化;
  2. 自定义TypeEvaluator需要重写evaluate()方法,计算对象的属性值并将其封装成一个新对象返回;

2.自定义插值器

下面,我们就来创建自己的Interpolator。上面已经讲得非常清楚了,Interpolator的关键在于公式。我想创建的Interpolator名字叫HesitateInterPolator:起始时速度全速,快到一半时减速到0,然后加速直到终点,
用图形来表示即:
这里写图片描述
用数学公式来表示即:
这里写图片描述
我们只需要实现Interpolator接口,然后实现其中的float getInterpolation(float t)接口即可:

public class HesitateInterpolator implements Interpolator {
    public HesitateInterpolator() {}
    public float getInterpolation(float t) {
      float x=2.0f*t-1.0f;
      return 0.5f*(x*x*x + 1.0f);
    }
}

3.自定义类型估值

public class ColorEvaluator implements TypeEvaluator {  

    private int mCurrentRed = -1;  

    private int mCurrentGreen = -1;  

    private int mCurrentBlue = -1;  

    @Override  
    public Object evaluate(float fraction, Object startValue, Object endValue) {  
        String startColor = (String) startValue;  
        String endColor = (String) endValue;  
        int startRed = Integer.parseInt(startColor.substring(1, 3), 16);  
        int startGreen = Integer.parseInt(startColor.substring(3, 5), 16);  
        int startBlue = Integer.parseInt(startColor.substring(5, 7), 16);  
        int endRed = Integer.parseInt(endColor.substring(1, 3), 16);  
        int endGreen = Integer.parseInt(endColor.substring(3, 5), 16);  
        int endBlue = Integer.parseInt(endColor.substring(5, 7), 16);  
        // 初始化颜色的值  
        if (mCurrentRed == -1) {  
            mCurrentRed = startRed;  
        }  
        if (mCurrentGreen == -1) {  
            mCurrentGreen = startGreen;  
        }  
        if (mCurrentBlue == -1) {  
            mCurrentBlue = startBlue;  
        }  
        // 计算初始颜色和结束颜色之间的差值  
        int redDiff = Math.abs(startRed - endRed);  
        int greenDiff = Math.abs(startGreen - endGreen);  
        int blueDiff = Math.abs(startBlue - endBlue);  
        int colorDiff = redDiff + greenDiff + blueDiff;  
        if (mCurrentRed != endRed) {  
            mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0,  
                    fraction);  
        } else if (mCurrentGreen != endGreen) {  
            mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff,  
                    redDiff, fraction);  
        } else if (mCurrentBlue != endBlue) {  
            mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff,  
                    redDiff + greenDiff, fraction);  
        }  
        // 将计算出的当前颜色的值组装返回  
        String currentColor = "#" + getHexString(mCurrentRed)  
                + getHexString(mCurrentGreen) + getHexString(mCurrentBlue);  
        return currentColor;  
    }  

    /** 
     * 根据fraction值来计算当前的颜色。 
     */  
    private int getCurrentColor(int startColor, int endColor, int colorDiff,  
            int offset, float fraction) {  
        int currentColor;  
        if (startColor > endColor) {  
            currentColor = (int) (startColor - (fraction * colorDiff - offset));  
            if (currentColor < endColor) {  
                currentColor = endColor;  
            }  
        } else {  
            currentColor = (int) (startColor + (fraction * colorDiff - offset));  
            if (currentColor > endColor) {  
                currentColor = endColor;  
            }  
        }  
        return currentColor;  
    }  

    /** 
     * 将10进制颜色值转换成16进制。 
     */  
    private String getHexString(int value) {  
        String hexString = Integer.toHexString(value);  
        if (hexString.length() == 1) {  
            hexString = "0" + hexString;  
        }  
        return hexString;  
    }  

}  

参考目录:
1. Interpolators详解
2. 公共技术点之Android动画基础
3. Android动画系列

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值