Android中的Interpolator

  Interpolator用于动画中的时间插值,其作用就是把0到1的浮点值变化映射到另一个浮点值变化。

  本文列出Android API提供的Interpolator的若干种实现,列出源码,并且用一个程序绘制出其数学曲线。(项目链接附在文后)。

AccelerateDecelerateInterpolator

/**
* An interpolator where the rate of change starts and ends slowly but
* accelerates through the middle.
*
*/
public class AccelerateDecelerateInterpolator implements Interpolator {
public AccelerateDecelerateInterpolator() {
} @SuppressWarnings({"UnusedDeclaration"})
public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
} public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
}

AccelerateInterpolator

/**
* An interpolator where the rate of change starts out slowly and
* and then accelerates.
*
*/
public class AccelerateInterpolator implements Interpolator {
private final float mFactor;
private final double mDoubleFactor; public AccelerateInterpolator() {
mFactor = 1.0f;
mDoubleFactor = 2.0;
} /**
* Constructor
*
* @param factor 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)
*/
public AccelerateInterpolator(float factor) {
mFactor = factor;
mDoubleFactor = 2 * mFactor;
} public AccelerateInterpolator(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();
} public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return input * input;
} else {
return (float)Math.pow(input, mDoubleFactor);
}
}
}

AnticipateInterpolator

/**
* An interpolator where the change starts backward then flings forward.
*/
public class AnticipateInterpolator implements Interpolator {
private final float mTension; public AnticipateInterpolator() {
mTension = 2.0f;
} /**
* @param tension Amount of anticipation. When tension equals 0.0f, there is
* no anticipation and the interpolator becomes a simple
* acceleration interpolator.
*/
public AnticipateInterpolator(float tension) {
mTension = tension;
} public AnticipateInterpolator(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();
} public float getInterpolation(float t) {
// a(t) = t * t * ((tension + 1) * t - tension)
return t * t * ((mTension + 1) * t - mTension);
}
}

AnticipateOvershootInterpolator

/**
* An interpolator where the change starts backward then flings forward and overshoots
* the target value and finally goes back to the final value.
*/
public class AnticipateOvershootInterpolator implements Interpolator {
private final float mTension; public AnticipateOvershootInterpolator() {
mTension = 2.0f * 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.
*/
public AnticipateOvershootInterpolator(float tension) {
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 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.
*/
public AnticipateOvershootInterpolator(float tension, float extraTension) {
mTension = tension * extraTension;
} public AnticipateOvershootInterpolator(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();
} private static float a(float t, float s) {
return t * t * ((s + 1) * t - s);
} private static float o(float t, float s) {
return t * t * ((s + 1) * t + s);
} public float getInterpolation(float t) {
// 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) return 0.5f * a(t * 2.0f, mTension);
else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
}
}

BounceInterpolator

/**
* An interpolator where the change bounces at the end.
*/
public class BounceInterpolator implements Interpolator {
public BounceInterpolator() {
} @SuppressWarnings({"UnusedDeclaration"})
public BounceInterpolator(Context context, AttributeSet attrs) {
} private static float bounce(float t) {
return t * t * 8.0f;
} public float getInterpolation(float t) {
// _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) return bounce(t);
else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
else return bounce(t - 1.0435f) + 0.95f;
}
}

CycleInterpolator

/**
* Repeats the animation for a specified number of cycles. The
* rate of change follows a sinusoidal pattern.
*
*/
public class CycleInterpolator implements Interpolator {
public CycleInterpolator(float cycles) {
mCycles = cycles;
} public CycleInterpolator(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();
} public float getInterpolation(float input) {
return (float)(Math.sin(2 * mCycles * Math.PI * input));
} private float mCycles;
}

  参数为2时的曲线:

DecelerateInterpolator

/**
* An interpolator where the rate of change starts out quickly and
* and then decelerates.
*
*/
public class DecelerateInterpolator implements Interpolator {
public DecelerateInterpolator() {
} /**
* Constructor
*
* @param factor 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)
*/
public DecelerateInterpolator(float factor) {
mFactor = factor;
} public DecelerateInterpolator(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();
} public float getInterpolation(float input) {
float result;
if (mFactor == 1.0f) {
result = (float)(1.0f - (1.0f - input) * (1.0f - input));
} else {
result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));
}
return result;
} private float mFactor = 1.0f;
}

LinearInterpolator

/**
* An interpolator where the rate of change is constant
*
*/
public class LinearInterpolator implements Interpolator { public LinearInterpolator() {
} public LinearInterpolator(Context context, AttributeSet attrs) {
} public float getInterpolation(float input) {
return input;
}
}

OvershootInterpolator

/**
* An interpolator where the change flings forward and overshoots the last value
* then comes back.
*/
public class OvershootInterpolator implements Interpolator {
private final float mTension; public OvershootInterpolator() {
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.
*/
public OvershootInterpolator(float tension) {
mTension = tension;
} public OvershootInterpolator(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();
} public float getInterpolation(float t) {
// _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;
}
}

项目链接:

  https://github.com/mengdd/HelloInterpolator.git

Android中的Interpolator的更多相关文章

  1. Android中的动画机制

          1 逐帧动画   逐帧动画 就是一系列的图片按照一定的顺序展示的过程.   逐帧动画很简单, 只需要在drawable中或者anim中定义一个Animation-list 其中包含多个it ...

  2. Android中自定义属性(attrs.xml,TypedArray的使用)

    做Android布局是件很享受的事,这得益于他良好的xml方式.使用xml可以快速有效的为软件定义界面.可是有时候我们总感觉官方定义的一些基本组件不够用,自定义组件就不可避免了.那么如何才能做到像官方 ...

  3. [Android]GOF23种设计模式 & Android中的设计模式

    GOF23种设计模式 设计原则: 1. 单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因 2. 开放-封闭原则(OCP):软件实体(类.模块.函数等)应该可以扩展,但是不可修改.即对 ...

  4. Android动画之Interpolator和AnimationSet

    AnimationSet可以加入Animation,加入之后设置AnimationSet对加入的所有Animation都有效. AnimationSet anim=new AnimationSet(t ...

  5. Android中xml设置Animation动画效果详解

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  6. android中设置Animation 动画效果

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  7. Android中的动画学习总结

    android中动画可分为三种:帧动画,补间动画,和属性动画.其中属性动画是google推荐的,它可以实现前面两种动画的效果,运用起来更加灵活. 帧动画:顾名思义,就是一帧一帧的图片,快速播放形成的动 ...

  8. android中列表的滑动删除仿ios滑动删除

    大家是不是觉得ios列表的滑动删除效果很酷炫?不用羡慕android也可以实现相同的效果 并且可以自定义效果,比如左滑删除,置顶,收藏,分享等等 其实就是自定义listview重写listview方法 ...

  9. android 中动画

    详解Android动画之Frame Animation 写出动画效果的xml文件布局基本代码如下: <?xml version="1.0" encoding="ut ...

随机推荐

  1. Spring应用教程-2 方法注入

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bea ...

  2. ListView:The content of the adapter has changed but ListView did not receive a notification终极解决方法

    使用ListView时遇到如下的异常信息: 10-26 18:30:45.085: E/AndroidRuntime(7323): java.lang.IllegalStateException: T ...

  3. 简单设置,解决使用webpack前后端跨域发送cookie的问题

    最近用vue来做项目,用webpack来做前端自动化构建.webpack-dev-server会在本地搭建一个服务器,在和后端调试的时候,就会涉及到跨域的问题. 刚开始时,没有用vue-cli来构建项 ...

  4. 【模式匹配】KMP算法的来龙去脉

    1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串\(T\)中是否出现该模式串\(P\),即\(P\)为\(T\)的子串.特别地,定义主串为\(T[0 \dots n-1]\),模 ...

  5. HTML5 Web 客户端五种离线存储方式汇总

    最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...

  6. 百度Map与HT for Web结合的GIS网络拓扑应用

    在<HT for Web整合OpenLayers实现GIS地图应用>篇中介绍了HT for Web与OpenLayers的整合,不少朋友反应国内用得比较多的还是百度地图,虽然HT整合百度地 ...

  7. 实现在GET请求下调用WCF服务时传递对象(复合类型)参数

    WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...

  8. membership 启用 roleManager 抛出异常:未能加载文件或程序集MySql.Web

    在vs2013中新建一个ASP.NET MVC 4 WEB 应用程序,使用“基本”模板.web.config中默认使用forms认证方式,并添加了membership的配置. <roleMana ...

  9. xamarin.ios 实现圆形进度条

    using System; using UIKit; using System.Drawing; using CoreAnimation; namespace PMM { public class P ...

  10. 怎样解决PowerDesigner15出现许可证过期问题?

    今天打开PowerDesigner软件,出现许可证过期问题,怎样解决 1)打开软件安装路径(通过搜索打开文件所在路径或通过软件图标的属性打开)