屬性動畫中有一個重要的概念就是插值器——Interpolator,根據流失的時間因子計算得到屬性因子。Android中預設的插值器是AccelerateDecelerateInterpolator,內建了很多插值器,本文將以一個例子介紹各種插值器的效果,以及如何自定義Interpolator。
話不多說,先看demo,如下圖:
官方Interpolator介紹
除了最後一個是自定義Interpolator外,其他都是系統自帶的。下面主要介紹下效果就好了:
- AccelerateDecelerateInterpolator:先加速、再減速,預設的插值器
- LinearInterpolator:線性插值器
- AccelerateInterpolator:加速
- DecelerateInterpolator:減速
- AnticipateInterpolator:開始時先反向
- BounceInterpolator:達到最終位置會先反彈,類似彈彈球著地的效果
- OvershootInterpolator:達到最終位置會超出一些
- AnticipateOvershootInterpolator:AnticipateInterpolator與OvershootInterpolator的結合
- CycleInterpolator:正弦效果,可以指定迴盪的次數
- PathInterpolator:根據指定的path進行運動,可以實現貝塞爾曲線
Interpolator既可以在程式碼中指定給動畫,同樣也可以在xml檔案中使用,這塊可以到參考文章中檢視。
自定義Interpolator
先介紹一個網站,裡面有各種Interpolator的效果以及數學公式定義,網址是 inloop.github.io/interpolato… 。
先看官方Interpolator找找靈感
Interpolator的核心是下面這個方法:
float getInterpolation(float input);
複製程式碼
其中input就是流失的時間因子,範圍是[0,1],輸出是屬性因子。
LinearInterpolator的函式是個一次函式,樣式如下:
相對應的,LinearInterpolator的方法實現如下:
public float getInterpolation(float input) {
return input;
}
複製程式碼
而AccelerateInterpolator的函式是個二次函式,樣式如下:
相對應地,實現如下:
public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return input * input;
} else {
return (float)Math.pow(input, mDoubleFactor);
}
}
複製程式碼
看完了官方的兩個例子,再來看看如何自定義Interpolator。
自定義Interpolator——SpringInterpolator
可以看到,我們自定義的Interpolator在達到終點後,有多次震盪的效果,是不是很像彈簧?這個可以通過自定義Interpolator實現,也可以通過DynamicAnimation實現,具有可以參考讓View具有彈性效果的動畫——SpringAnimation。
SpringInterpolator的函式很複雜,樣式如下:
然後就是根據函式實現方法了,具體如下:
class SpringInterpolator(val factor: Float) : Interpolator{
override fun getInterpolation(input: Float): Float {
return (Math.pow(2.0, -10.0 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1).toFloat()
}
}
複製程式碼
這麼複雜的函式,如果你問我是怎麼會的,那我只能告訴你,去上面那個網址看吧,你會發現自定義Interpolator原來這麼容易。
其實自定義Interpolator的核心就是這個上面的函式樣式,以及將其再轉換成程式碼就ok了。
總結
關於程式碼,參考Github
參考
- developer.android.com/guide/topic…
- wiki.jikexueyuan.com/project/and…
- medium.com/mindorks/un…
- robots.thoughtbot.com/android-int…
關注我的技術公眾號,不定期會有技術文章推送,不敢說優質,但至少是我自己的學習心得。微信掃一掃下方二維碼即可關注: