Android屬性動畫(三) TimeInterpolator(插值器)
OK,繼續學習屬性動畫,本篇文章是屬性動畫系列的第三篇文章了,今天來學習一下屬性動畫中的TimeInterpolator,如果你對屬性動畫還不太熟悉,可以點選下面的連結學習一下前兩篇文章的知識:
1.介紹
先說說Interpolator,在Android 1.0版本中就已經有Interpolator介面了,可以翻譯成插值器,用於計算補間動畫的變化速率。Android團隊在3.0版本中引入了屬性動畫,同時新增了TimeInterpolator介面,Interpolator繼承於TimeInterpolator,這就使得Interpolator的實現類可以直接拿到屬性動畫中使用。
可以看到,Android系統中已經內建了很多實現類了,比如AccelerateInterpolator就是加速運動的插值器,DecelerateInterpolator是減速運動的插值器,LinearInterpolator是勻速運動的差值器。
舉個栗子,系統預設的插值器AccelerateDecelerateInterpolator(在動畫開始與結束的地方速率改變比較慢,在中間的時候加速),看下原始碼:
public class AccelerateDecelerateInterpolator extends BaseInterpolator
implements NativeInterpolatorFactory {
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;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
}
}
主要看下getInterpolation方法,接收一個float型別的input引數,input引數是由系統計算傳入的,變化很有規律,就是根據動畫的時長從0到1勻速增加,傳入到下面的公式中,計算出當前屬性值改變的百分比,這個值就是我們在上一篇文章中提到的fraction引數,TypeEvaluator(估值器)就是根據fraction引數來計算當前的屬性值的。
AccelerateDecelerateInterpolator的變化曲線:
2.自定義TimeInterpolator
TimeInterpolator的實現類雖然很多,但不一定能滿足我們的需求,這時候就需要我們來自定義一個TimeInterpolator來完成各種各樣複雜的動畫效果,接下來我們就自定義一個TimeInterpolator來實現一下圖片的回彈效果,先看下實現後的效果:
首先定義一個JellyInterpolator類實現TimeInterpolator介面,重寫getInterpolation方法:
public class JellyInterpolator implements TimeInterpolator {
// 因子數值越小振動頻率越高
private float factor;
public JellyInterpolator() {
this.factor = 0.15f;
}
@Override
public float getInterpolation(float input) {
return (float) (Math.pow(2, -10 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1);
}
}
看下JellyInterpolator的變化曲線:
在Activity中設定屬性動畫:
public class InterpolatorActivity extends AppCompatActivity {
@BindView(R.id.image)
ImageView image;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interpolator);
ButterKnife.bind(this);
}
@OnClick(R.id.image)
public void onClick() {
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(image, "scaleX", 0f, 1f);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(image, "scaleY", 0f, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
// 設定插值器
animatorSet.setInterpolator(new JellyInterpolator());
animatorSet.setDuration(3000);
animatorSet.start();
}
}
到這裡一個自定義的TimeInterpolator就完成了,主要的難點就在公式計算了,分享一個視覺化插值器的網站,其中內建了一些插值器公式,還可以檢視動畫演示效果。
3.寫在最後
原始碼已託管到GitHub上,歡迎Fork,覺得還不錯就Start一下吧!
歡迎同學們吐槽評論,如果你覺得本篇部落格對你有用,那麼就留個言或者頂一下吧(^-^)