android动画(一)Interpolator

来源:互联网 发布:快手视频编辑软件 编辑:程序博客网 时间:2024/04/29 08:30



 

cycleInterpolator 循环加速器

标签: androidencoding
 6411人阅读 评论(0) 收藏 举报
 分类:
 

如果要让动画连续执行多次,可以使用cycleInterpolator加速器

 

设置方法:

<?xml version="1.0" encoding="utf-8"?>

<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />





http://my.oschina.net/banxi/blog/135633

http://my.oschina.net/banxi/blog/135633

http://my.oschina.net/banxi/blog/135633

http://my.oschina.net/banxi/blog/135633




android动画(一)Interpolator

发表于3年前(2013-06-04 23:19)   阅读(19272) | 评论(15) 47人收藏此文章, 我要收藏
22
android interplator

目录[-]

  • 一:简介
  • 二:简单插值器分析
  •    1.AccelerateInterpolator  加速插值器
  • 3.  AccelerateDecelerateInterpolator  加速减速插值器
  • 4. LinearInterpolator 线性插值器
  • 5. BounceInterpolator 弹跳插值器
  • 6.AnticipateInterpolator 回荡秋千插值器
  • 7. AnticipateOvershootInterpolator
  • 8. CycleInterpolator 正弦周期变化插值器
  • 9. OvershootInterpolator 
  • 一:简介

    interpolator可以翻译成插值器。

    Android中interpolator最底层的接口如下:


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    packageandroid.animation;
     
    /**
     * 时间插值器定义了一个动画的变化率。
     * 这让动画让非线性的移动轨迹,例如加速和减速。
     * <hr/>
     * A time interpolator defines the rate of change of an animation. This allows animations
     * to have non-linear motion, such as acceleration and deceleration.
     */
    publicinterface TimeInterpolator {
     
        /**
         * 将动画已经消耗的时间的分数映射到一个表示插值的分数。
         * 然后将插值与动画的变化值相乘来推导出当前已经过去的动画时间的动画变化量。
         * <hr/>
         * Maps a value representing the elapsed fraction of an animation to a value that represents
         * the interpolated fraction. This interpolated value is then multiplied by the change in
         * value of an animation to derive the animated value at the current elapsed animation time.
         *
         * @param input  一个0到1.0表示动画当前点的值,0表示开头。1表示结尾<br/> A value between 0 and 1.0 indicating our current point
         *        in the animation where 0 represents the start and 1.0 represents
         *        the end
         * @return   插值。它的值可以大于1来超出目标值,也小于0来空破底线。<br/>The interpolation value. This value can be more than 1.0 for
         *         interpolators which overshoot their targets, or less than 0 for
         *         interpolators that undershoot their targets.
         */
        floatgetInterpolation(floatinput);
    }


    TimeInterpolator是在Android API11时加入的之前类就叫Interpolator。

    现在Interpolatro继承了它。


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    packageandroid.view.animation;
     
    importandroid.animation.TimeInterpolator;
     
    /**
     *
     * 一个定义动画变化率的插值器。
     * 它允许对基本的(如透明,缩放,平移,旋转)进行加速,减速,重复等动画效果
     * <hr/>
     * An interpolator defines the rate of change of an animation. This allows
     * the basic animation effects (alpha, scale, translate, rotate) to be
     * accelerated, decelerated, repeated, etc.
     */
    publicinterface Interpolator extendsTimeInterpolator {
        // A new interface, TimeInterpolator, was introduced for the new android.animation
        // package. This older Interpolator interface extends TimeInterpolator so that users of
        // the new Animator-based animations can use either the old Interpolator implementations or
        // new classes that implement TimeInterpolator directly.
    }


    二:简单插值器分析

       注意下面的图,对应你脑海中的插值的大小应该是斜率。

       1.AccelerateInterpolator  加速插值器

      源代码如下:


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     *
     * 一个开始很慢然后不断加速的插值器。
     * <hr/>
     * An interpolator where the rate of change starts out slowly and
     * and then accelerates.
     *
     */
    publicclass AccelerateInterpolator implementsInterpolator {
        privatefinal float mFactor;
        privatefinal double mDoubleFactor;
     
        publicAccelerateInterpolator() {
            mFactor = 1.0f;
            mDoubleFactor = 2.0;
        }
     
        /**
         * Constructor
         *
         * @param factor
         *     动画的快慢度。将factor设置为1.0f会产生一条y=x^2的抛物线。
    增加factor到1.0f之后为加大这种渐入效果(也就是说它开头更加慢,结尾更加快)
         *   <br/>Degree to which the animation should be eased. Seting
         *        factor to 1.0f produces a y=x^2 parabola(抛物线). Increasing factor above
         *        1.0f  exaggerates the ease-in effect (i.e., it starts even
         *        slower and ends evens faster)
         */
        publicAccelerateInterpolator(floatfactor) {
            mFactor = factor;
            mDoubleFactor = 2* mFactor;
        }
     
        publicAccelerateInterpolator(Context context, AttributeSet attrs) {
            TypedArray a =
                    context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);
     
            mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);
            mDoubleFactor = 2* mFactor;
     
            a.recycle();
        }
     
        @Override
        publicfloat getInterpolation(floatinput) {
            if(mFactor == 1.0f) {
                returninput * input;
            }else{
                return(float)Math.pow(input, mDoubleFactor);
            }
        }
    }


     加速的快慢度由参数fractor决定。

    当fractor值为1.0f时,动画加速轨迹相当于一条y=x^2的抛物线。如下图:

    当fractor不为1时,轨迹曲线是y=x^(2*fractor)(0<x<=1)的曲线。

    示例:当fractor为4时,插值器的加速轨迹曲线如下图:

    如果你在使用AccelerateInterpolator时,想要那种一开始很慢,然后突然就很快的加速的动画效果的话。

    就将fractor设置大点。

    你可以到这里调试下你想要的抛物线效果:http://www.wolframalpha.com/input/?i=x%5E%282*3%29%280%3Cx%3C%3D1%29


    Android提供的一个不同factor的加速插值器:

    (1)accelerate_cubic, factor为1.5


    2. DecelerateInterpolator 减速插值器

    源代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     * 一个开始比较快然后减速的插值器
     * <hr/>
     * An interpolator where the rate of change starts out quickly and
     * and then decelerates.
     *
     */
    publicclass DecelerateInterpolator implementsInterpolator {
        publicDecelerateInterpolator() {
        }
     
        /**
         * Constructor
         *
         * @param factor
         *        动画的快慢度。将factor值设置为1.0f时将产生一条从上向下的y=x^2抛物线。
         *        增加factor到1.0f以上将使渐入的效果增强(也就是说,开头更快,结尾更慢)
         *        <br/>
         *        Degree to which the animation should be eased. Setting factor to 1.0f produces
         *        an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
         *        ease-out effect (i.e., it starts even faster and ends evens slower)
         */
        publicDecelerateInterpolator(floatfactor) {
            mFactor = factor;
        }
     
        publicDecelerateInterpolator(Context context, AttributeSet attrs) {
            TypedArray a =
                    context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);
     
            mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);
     
            a.recycle();
        }
     
        @Override
        publicfloat getInterpolation(floatinput) {
            floatresult;
            if(mFactor == 1.0f) {
                result = (1.0f - ((1.0f - input) * (1.0f - input)));
            }else{
                result = (float)(1.0f - Math.pow((1.0f - input), 2* mFactor));
            }
            returnresult;
        }
     
        privatefloat mFactor = 1.0f;
    }

    根据getInterpolationa(float input);方法可以知道。

    当fractor为1.0f。它减速的轨迹曲线为1-(1-x)^2。如下图:


    当fractor增大到4时,曲线轨迹如下图:


    3.  AccelerateDecelerateInterpolator  加速减速插值器

    源代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.util.AttributeSet;
     
    /**
     * 一个变化率开始慢从中间后开始变快。
     * <hr/>
     * An interpolator where the rate of change starts and ends slowly but
     * accelerates through the middle.
     *
     */
    publicclass AccelerateDecelerateInterpolator implementsInterpolator {
        publicAccelerateDecelerateInterpolator() {
        }
     
        @SuppressWarnings({"UnusedDeclaration"})
        publicAccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
        }
     
        @Override
        publicfloat getInterpolation(floatinput) {
            return(float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
        }
    }

    根据getInterpolation()方法可以得出其变化曲线如下:


    4. LinearInterpolator 线性插值器

    这可是最简单的插值器:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
     * An interpolator where the rate of change is constant
     *
     */
    publicclass LinearInterpolator implementsInterpolator {
     
        publicLinearInterpolator() {
        }
         
        publicLinearInterpolator(Context context, AttributeSet attrs) {
        }
         
        publicfloat getInterpolation(floatinput) {
            returninput;
        }
    }

    5. BounceInterpolator 弹跳插值器

     源代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.util.AttributeSet;
     
    /**
     * 这个插值器的插值在后面呈弹跳状态。
     * An interpolator where the change bounces at the end.
     */
    publicclass BounceInterpolator implementsInterpolator {
        publicBounceInterpolator() {
        }
     
        @SuppressWarnings({"UnusedDeclaration"})
        publicBounceInterpolator(Context context, AttributeSet attrs) {
        }
     
        privatestatic float bounce(floatt) {
            returnt * t * 8.0f;
        }
     
        @Override
        publicfloat getInterpolation(floatt) {
            // _b(t) = t * t * 8
            // bs(t) = _b(t) for t < 0.3535
            // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
            // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
            // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
            // b(t) = bs(t * 1.1226)
            t *= 1.1226f;
            if(t < 0.3535f)returnbounce(t);
            elseif (t < 0.7408f)returnbounce(t - 0.54719f) + 0.7f;
            elseif (t < 0.9644f)returnbounce(t - 0.8526f) + 0.9f;
            elsereturn bounce(t - 1.0435f) + 0.95f;
        }
    }

    根据getInterpolation()得到以下插值曲线图:

    (这个插值器的作图函数我得记录下来啊)

    ?
    1
    plot Piecewise[{ {(1.1226x)^2*8,0<x<0.3535}, {((1.1226x)-0.54719)^2*8+0.7,0.3535<=x<0.7408}, {((1.1226x)-0.8526)^2*8+0.9,0.7408<=x<0.9644}, {((1.1226x)-1.0435)^2*8+0.95,0.9644<=x<=1}}]

    6.AnticipateInterpolator 回荡秋千插值器

    这个插值器的值变化过程,可以想像成荡秋千时的一个段过程。(此时秋千已经在比较上面的位置了,一放手就可以荡下来)。你开始用力推向更上面,然后秋千终将荡回下面。

    tension值就好比推力的大小。

    源代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     * 一个开始向后荡,然后向前荡的插值器。
     * <hr/>
     * An interpolator where the change starts backward then flings forward.
     */
    publicclass AnticipateInterpolator implementsInterpolator {
        privatefinal float mTension;
     
        publicAnticipateInterpolator() {
            mTension = 2.0f;
        }
     
        /**
         * @param tension
         *  绷紧程度,当绷紧程序为0.0f时,也就没有了反向作用力。插值器将退化成一个y=x^3的加速插值器。
         * <br/>
         * Amount of anticipation. When tension equals 0.0f, there is
         *                no anticipation and the interpolator becomes a simple
         *                acceleration interpolator.
         */
        publicAnticipateInterpolator(floattension) {
            mTension = tension;
        }
     
        publicAnticipateInterpolator(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(attrs,
                    com.android.internal.R.styleable.AnticipateInterpolator);
     
            mTension =
                    a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension,2.0f);
     
            a.recycle();
        }
     
        @Override
        publicfloat getInterpolation(floatt) {
            // a(t) = t * t * ((tension + 1) * t - tension)
            returnt * t * (((mTension + 1) * t) - mTension);
        }
    }

    根据getInterpolation()方法。

    当tension为默认值2.0f时,曲线图如下:


    当tension值为4.0f时,曲线图如下:


    7. AnticipateOvershootInterpolator

    源代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     * 一个插值器它开始向上推,然后向下荡,荡过最低线。然后再回到最低线。
     * <hr/>
     * An interpolator where the change starts backward then flings forward and overshoots
     * the target value and finally goes back to the final value.
     */
    publicclass AnticipateOvershootInterpolator implementsInterpolator {
        privatefinal float mTension;
     
        publicAnticipateOvershootInterpolator() {
            mTension = 2.0f * 1.5f;
        }
     
        /**
         * @param tension
         *  anticipation/overshoot的比值。当和tension值为0.0f时,
         *  也就没有anticipation/overshoot的比值了,插值器退化为一个加速/减速插值器。
         *  <br/>
         * Amount of anticipation/overshoot. When tension equals 0.0f,
         *                there is no anticipation/overshoot and the interpolator becomes
         *                a simple acceleration/deceleration interpolator.
         */
        publicAnticipateOvershootInterpolator(floattension) {
            mTension = tension * 1.5f;
        }
     
        /**
         * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
         *                there is no anticipation/overshoot and the interpolator becomes
         *                a simple acceleration/deceleration interpolator.
         * @param extraTension
         * 乘以tension的值。例如,在上面构造函数中extraTension的值为1.5f
         * <br/>
         * Amount by which to multiply the tension. For instance,
         *                     to get the same overshoot as an OvershootInterpolator with
         *                     a tension of 2.0f, you would use an extraTension of 1.5f.
         */
        publicAnticipateOvershootInterpolator(floattension, floatextraTension) {
            mTension = tension * extraTension;
        }
     
        publicAnticipateOvershootInterpolator(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);
     
            mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *
                    a.getFloat(AnticipateOvershootInterpolator_extraTension,1.5f);
     
            a.recycle();
        }
     
        privatestatic float a(floatt, floats) {
            returnt * t * (((s + 1) * t) - s);
        }
     
        privatestatic float o(floatt, floats) {
            returnt * t * (((s + 1) * t) + s);
        }
     
        @Override
        publicfloat getInterpolation(floatt) {
            // a(t, s) = t * t * ((s + 1) * t - s)
                    // o(t, s) = t * t * ((s + 1) * t + s)
            // f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5
            // f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0
            if(t < 0.5f)return0.5f * a(t * 2.0f, mTension);
            elsereturn 0.5f * (o((t * 2.0f) - 2.0f, mTension) + 2.0f);
        }
    }


    根据getInterpolation()方法,

    可以得到当tension为默认值时,曲线图为:

    plot Piecewise[{{0.5((2x)*(2x)*((2+1)*2x-2)), 0<x<0.5}, {0.5*(((2x-2)*(2x-2)*((2+1)*(2x-2)+2))+2),0.5<=x<=1}}]

    (不知道我的plot函数写对了没?)

     

    8. CycleInterpolator 正弦周期变化插值器

    源代码:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     *
     * 以指定的周期重复动画。变化率曲线为正弦。
     * <hr/>
     * Repeats the animation for a specified number of cycles(周期). The
     * rate of change follows a sinusoidal(正弦) pattern.
     *
     */
    publicclass CycleInterpolator implementsInterpolator {
        /**
         *
         * @param cycles 要重复的周期数
         */
        publicCycleInterpolator(floatcycles) {
            mCycles = cycles;
        }
     
        publicCycleInterpolator(Context context, AttributeSet attrs) {
            TypedArray a =
                    context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);
     
            mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);
     
            a.recycle();
        }
     
        @Override
        publicfloat getInterpolation(floatinput) {
            return(float)(Math.sin(2* mCycles * Math.PI * input));
        }
     
        privatefloat mCycles;
    }
    当cycle时为1时,即变化一周时,曲线图如下:


    9. OvershootInterpolator 

    源代码:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    packageandroid.view.animation;
     
    importandroid.content.Context;
    importandroid.content.res.TypedArray;
    importandroid.util.AttributeSet;
     
    /**
     * An interpolator where the change flings forward and overshoots the last value
     * then comes back.
     */
    publicclass OvershootInterpolator implementsInterpolator {
        privatefinal float mTension;
     
        publicOvershootInterpolator() {
            mTension = 2.0f;
        }
     
        /**
         * @param tension Amount of overshoot. When tension equals 0.0f, there is
         *                no overshoot and the interpolator becomes a simple
         *                deceleration interpolator.
         */
        publicOvershootInterpolator(floattension) {
            mTension = tension;
        }
     
        publicOvershootInterpolator(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(attrs,
                    com.android.internal.R.styleable.OvershootInterpolator);
     
            mTension =
                    a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension,2.0f);
     
            a.recycle();
        }
     
        @Override
        publicfloat getInterpolation(floatt) {
            // _o(t) = t * t * ((tension + 1) * t + tension)
            // o(t) = _o(t - 1) + 1
            t -= 1.0f;
            return(t * t * (((mTension + 1) * t) + mTension)) + 1.0f;
            //plot {(x-1)(x-1)((tension+1)(x-1)+tension)+1,(0<x<=1)}
        }
    }

    当tension为默认值2时,曲线图如下:

    当tension的值为4时,曲线图如下:

    通过学习了解Android自带的这些Interpolator,我们可以很好的根据自己的使用场景使用这些Interpolator了。也可以很容易的写出我们自己的Interpolator。




    0 0