Android 动画自定义补间器 Interpolator
前面我们提到过,所有的补间器 (Interpolator) 都继承自 TimeInterpolator
,然后又有很多子类
AccelerateDecelerateInterpolator AccelerateInterpolator AnticipateInterpolator AnticipateOvershootInterpolator BaseInterpolator BounceInterpolator CycleInterpolator DecelerateInterpolator Interpolator LinearInterpolator OvershootInterpolator PathInterpolator
getInterpolation() 方法
TimeInterpolator
只有一个虚方法 getInterpolation()
原型如下
float getInterpolation ( float input)
将代表动画流逝部分的值映射到表示插值部分的值,然后将该内插值乘以动画值的变化以导出当前流逝的动画时间的动画值
参数 | 说明 |
---|---|
input | 介于 0 和 1.0 之间的值,表示我们在动画中的当前点 其中 0 表示开始,1.0 表示结束 |
返回
类型 | 说明 |
---|---|
float | 内插值 对于超出其目标的内插器,该值可以大于 1.0 对于低于其目标的内插器,该值可以小于 0 |
自定义 Interpolator
知道了其它动画是怎么实现的之后,就可以继承 TimeInterpolator
接口实现自己的补间器
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); } } }
使用时可以调用 setInterpolator(new DecelerateAccelerateInterpolator())
范例
-
创建一个 空的 Android 项目
cn.twle.android.InterpolatorCustom
-
修改
activity_main.xml
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/ms_textview" android:background="#ff0000" android:layout_width="64dp" android:layout_height="64dp"/> </LinearLayout>
-
创建
DecelerateAccelerateInterpolator.java
package cn.twle.android.interpolatorcustom; import android.animation.TimeInterpolator; public 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); } } }
-
修改
MainActivity.java
package cn.twle.android.interpolatorcustom; import android.animation.ValueAnimator; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.RelativeLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { TextView ms_textview; float scale; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scale = MainActivity.this.getResources().getDisplayMetrics().density; ms_textview = findViewById(R.id.ms_textview); final int x = ms_textview.getLeft(); final int y = ms_textview.getTop(); ValueAnimator xValue = ValueAnimator.ofInt(0,600); xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int cur = (int) animation.getAnimatedValue(); ms_textview.layout( x+ cur, y+ cur, x+cur+ dp2px(64), y+cur+dp2px(64) ); } }); xValue.setDuration(3000L); xValue.setInterpolator(new DecelerateAccelerateInterpolator()); xValue.start(); } public int dp2px(float dpValue){ return (int)(dpValue* scale+0.5f); } }