OK采蚀,繼續(xù)學(xué)習(xí)屬性動(dòng)畫(huà)咪惠,本篇文章是屬性動(dòng)畫(huà)系列的第三篇文章了,今天來(lái)學(xué)習(xí)一下屬性動(dòng)畫(huà)中的TimeInterpolator疏尿,如果你對(duì)屬性動(dòng)畫(huà)還不太熟悉瘟芝,可以點(diǎn)擊下面的鏈接學(xué)習(xí)一下前兩篇文章的知識(shí):
《Android屬性動(dòng)畫(huà)(一) 初識(shí)基本用法》
《Android屬性動(dòng)畫(huà)(二) ValueAnimator的實(shí)際應(yīng)用 & 自定義TypeEvaluator》
1.介紹
先說(shuō)說(shuō)Interpolator,在Android 1.0版本中就已經(jīng)有Interpolator接口了褥琐,可以翻譯成插值器锌俱,用于計(jì)算補(bǔ)間動(dòng)畫(huà)的變化速率。Android團(tuán)隊(duì)在3.0版本中引入了屬性動(dòng)畫(huà)敌呈,同時(shí)新增了TimeInterpolator接口贸宏,Interpolator繼承于TimeInterpolator,這就使得Interpolator的實(shí)現(xiàn)類可以直接拿到屬性動(dòng)畫(huà)中使用驱富。
看下TimeInterpolator的實(shí)現(xiàn)類:
可以看到锚赤,Android系統(tǒng)中已經(jīng)內(nèi)置了很多實(shí)現(xiàn)類了,比如AccelerateInterpolator就是加速運(yùn)動(dòng)的插值器褐鸥,DecelerateInterpolator是減速運(yùn)動(dòng)的插值器线脚,LinearInterpolator是勻速運(yùn)動(dòng)的差值器。
舉個(gè)栗子叫榕,系統(tǒng)默認(rèn)的插值器AccelerateDecelerateInterpolator(在動(dòng)畫(huà)開(kāi)始與結(jié)束的地方速率改變比較慢浑侥,在中間的時(shí)候加速),看下源碼:
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方法晰绎,接收一個(gè)float類型的input參數(shù)寓落,input參數(shù)是由系統(tǒng)計(jì)算傳入的,變化很有規(guī)律荞下,就是根據(jù)動(dòng)畫(huà)的時(shí)長(zhǎng)從0到1勻速增加伶选,傳入到下面的公式中,計(jì)算出當(dāng)前屬性值改變的百分比尖昏,這個(gè)值就是我們?cè)谏弦黄恼轮刑岬降膄raction參數(shù)仰税,TypeEvaluator(估值器)就是根據(jù)fraction參數(shù)來(lái)計(jì)算當(dāng)前的屬性值的。
AccelerateDecelerateInterpolator的變化曲線:
2.自定義TimeInterpolator
TimeInterpolator的實(shí)現(xiàn)類雖然很多抽诉,但不一定能滿足我們的需求陨簇,這時(shí)候就需要我們來(lái)自定義一個(gè)TimeInterpolator來(lái)完成各種各樣復(fù)雜的動(dòng)畫(huà)效果,接下來(lái)我們就自定義一個(gè)TimeInterpolator來(lái)實(shí)現(xiàn)一下圖片的回彈效果迹淌,先看下實(shí)現(xiàn)后的效果:
首先定義一個(gè)JellyInterpolator類實(shí)現(xiàn)TimeInterpolator接口河绽,重寫getInterpolation方法:
public class JellyInterpolator implements TimeInterpolator {
// 因子數(shù)值越小振動(dòng)頻率越高
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中設(shè)置屬性動(dòng)畫(huà):
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);
// 設(shè)置插值器
animatorSet.setInterpolator(new JellyInterpolator());
animatorSet.setDuration(3000);
animatorSet.start();
}
}
到這里一個(gè)自定義的TimeInterpolator就完成了,主要的難點(diǎn)就在公式計(jì)算了唉窃,分享一個(gè)可視化插值器的網(wǎng)站耙饰,其中內(nèi)置了一些插值器公式,還可以查看動(dòng)畫(huà)演示效果纹份。
Interpolator:http://inloop.github.io/interpolator/
3.寫在最后
源碼已托管到GitHub上榔幸,歡迎Fork,覺(jué)得還不錯(cuò)就Start一下吧!
GitHub地址:https://github.com/alidili/PropertyAnimationDemo
歡迎同學(xué)們吐槽評(píng)論削咆,如果你覺(jué)得本篇博客對(duì)你有用牍疏,那么就留個(gè)言或者點(diǎn)下喜歡吧(^-^)