Android 動畫:插值器(Interpolator)

前言

動畫的使用 是Android開發(fā)中常用的知識

可是動畫的種類繁多、使用復雜,每當需要采用自定義動畫 實現(xiàn) 復雜的動畫效果時,很多開發(fā)者就顯得束手無策

Android中 補間動畫 & 屬性動畫實現(xiàn)動畫的原理是:

實現(xiàn)原理

其中,步驟2中的 插值器(Interpolator)和估值器(TypeEvaluator)是實現(xiàn) 復雜動畫效果的關鍵

本文主要講解 將詳細講解 插值器(Interpolator),通過閱讀本文你將能輕松實現(xiàn)復雜的動畫效果

關于Android動畫的系列文章

動畫的使用,請參考文章:

Android 屬性動畫:這是一篇很詳細的 屬性動畫 總結(jié)&攻略

Android 動畫:手把手教你使用 補間動畫

Android 逐幀動畫:關于 逐幀動畫 的使用都在這里了!

Android 動畫:你真的會使用插值器與估值器嗎?(含詳細實例教學)

自定義View的原理,請參考文章:

(1)自定義View基礎 - 最易懂的自定義View原理系列

(2)自定義View Measure過程 - 最易懂的自定義View原理系列

(3)自定義View Layout過程 - 最易懂的自定義View原理系列

(4)自定義View Draw過程- 最易懂的自定義View原理系列

自定義View的應用,請參考文章:

手把手教你寫一個完整的自定義View

Path類的最全面詳解 - 自定義View應用系列

Canvas類的最全面詳解 - 自定義View應用系列

為什么你的自定義View wrap_content不起作用?

目錄

示意圖

1. 簡介

定義:Android實現(xiàn)動畫效果中的一個輔助接口

作用:設置 屬性值 從初始值過渡到結(jié)束值 的變化規(guī)律

如勻速、加速 & 減速 等等

即確定了 動畫效果變化的模式,如勻速變化、加速變化 等等

2. 應用場景

實現(xiàn)非線性運動的動畫效果

非線性運動:動畫改變的速率不是一成不變的,如加速 & 減速運動都屬于非線性運動

3. 具體使用

插值器在動畫的使用有兩種方式:在XML / Java代碼中設置:

3.1 XML設置

主要是設置插值器屬性android:interpolator

<?xml version="1.0" encoding="utf-8"?>>

3.2 Java設置

Button mButton=(Button)findViewById(R.id.Button);// 步驟1:創(chuàng)建 需要設置動畫的 視圖ViewAnimation alphaAnimation=newAlphaAnimation(1,0);// 步驟2:創(chuàng)建透明度動畫的對象 & 設置動畫效果alphaAnimation.setDuration(3000);Interpolator overshootInterpolator=newOvershootInterpolator();// 步驟3:創(chuàng)建對應的插值器類對象alphaAnimation.setInterpolator(overshootInterpolator);// 步驟4:給動畫設置插值器mButton.startAnimation(alphaAnimation);// 步驟5:播放動畫

那么使用插值器時的資源ID是什么呢?即有哪些類型的插值器可供我們使用呢?

插值器分為兩種:Android內(nèi)置默認 & 自定義,下面我將詳細介紹

4. 系統(tǒng)內(nèi)置插值器

4.1 類型

Android內(nèi)置了 9 種內(nèi)置的插值器實現(xiàn):

示意圖

4.2 具體使用

當在XML文件設置插值器時,只需傳入對應的插值器資源ID即可

當在Java代碼設置插值器時,只需創(chuàng)建對應的插值器對象即可

系統(tǒng)默認的插值器是AccelerateDecelerateInterpolator,即先加速后減速

4.3 效果圖

效果圖

使用Android內(nèi)置的插值器能滿足大多數(shù)的動畫需求

如果上述9個插值器無法滿足需求,還可以自定義插值器

下面將介紹如何自定義插值器(Interpolator)

5. 自定義插值器

5.1 本質(zhì)

根據(jù)動畫的進度(0%-100%)計算出當前屬性值改變的百分比

5.2 實現(xiàn)方式

自定義插值器需要實現(xiàn)Interpolator/TimeInterpolator接口 & 復寫getInterpolation()

補間動畫 實現(xiàn)Interpolator接口;屬性動畫實現(xiàn)TimeInterpolator接口

TimeInterpolator接口是屬性動畫中新增的,用于兼容Interpolator接口,這使得所有過去的Interpolator實現(xiàn)類都可以直接在屬性動畫使用

// Interpolator接口publicinterfaceInterpolator{// 內(nèi)部只有一個方法floatgetInterpolation(floatinput){// 參數(shù)說明// input值值變化范圍是0-1,且隨著動畫進度(0% - 100% )均勻變化// 即動畫開始時,input值 = 0;動畫結(jié)束時input = 1// 而中間的值則是隨著動畫的進度(0% - 100%)在0到1之間均勻增加...// 插值器的計算邏輯returnxxx;// 返回的值就是用于估值器繼續(xù)計算的fraction值,下面會詳細說明}// TimeInterpolator接口// 同上publicinterfaceTimeInterpolator{floatgetInterpolation(floatinput);}

在學習自定義插值器前,我們先來看兩個已經(jīng)實現(xiàn)好的系統(tǒng)內(nèi)置差值器:

勻速插值器:LinearInterpolator

先加速再減速 插值器:AccelerateDecelerateInterpolator

// 勻速差值器:LinearInterpolator@HasNativeInterpolatorpublicclassLinearInterpolatorextendsBaseInterpolatorimplementsNativeInterpolatorFactory{// 僅貼出關鍵代碼...publicfloatgetInterpolation(floatinput){returninput;// 沒有對input值進行任何邏輯處理,直接返回// 即input值 = fraction值// 因為input值是勻速增加的,因此fraction值也是勻速增加的,所以動畫的運動情況也是勻速的,所以是勻速插值器}// 先加速再減速 差值器:AccelerateDecelerateInterpolator@HasNativeInterpolatorpublicclassAccelerateDecelerateInterpolatorimplementsInterpolator,NativeInterpolatorFactory{// 僅貼出關鍵代碼...publicfloatgetInterpolation(floatinput){return(float)(Math.cos((input+1)*Math.PI)/2.0f)+0.5f;// input的運算邏輯如下:// 使用了余弦函數(shù),因input的取值范圍是0到1,那么cos函數(shù)中的取值范圍就是π到2π。// 而cos(π)的結(jié)果是-1,cos(2π)的結(jié)果是1// 所以該值除以2加上0.5后,getInterpolation()方法最終返回的結(jié)果值還是在0到1之間。只不過經(jīng)過了余弦運算之后,最終的結(jié)果不再是勻速增加的了,而是經(jīng)歷了一個先加速后減速的過程// 所以最終,fraction值 = 運算后的值 = 先加速后減速// 所以該差值器是先加速再減速的}}

從上面看出,自定義插值器的關鍵在于:對input值 根據(jù)動畫的進度(0%-100%)通過邏輯計算 計算出當前屬性值改變的百分比

下面我將用一個實例來說明該如何自定義插值器

5.3 實例說明

下面,我將寫一個自定義Interpolator:先減速后加速。

步驟1:根據(jù)需求實現(xiàn)Interpolator接口

DecelerateAccelerateInterpolator.java

publicclassDecelerateAccelerateInterpolatorimplementsTimeInterpolator{@OverridepublicfloatgetInterpolation(floatinput){floatresult;if(input<=0.5){result=(float)(Math.sin(Math.PI*input))/2;// 使用正弦函數(shù)來實現(xiàn)先減速后加速的功能,邏輯如下:// 因為正弦函數(shù)初始弧度變化值非常大,剛好和余弦函數(shù)是相反的// 隨著弧度的增加,正弦函數(shù)的變化值也會逐漸變小,這樣也就實現(xiàn)了減速的效果。// 當弧度大于π/2之后,整個過程相反了過來,現(xiàn)在正弦函數(shù)的弧度變化值非常小,漸漸隨著弧度繼續(xù)增加,變化值越來越大,弧度到π時結(jié)束,這樣從0過度到π,也就實現(xiàn)了先減速后加速的效果}else{result=(float)(2-Math.sin(Math.PI*input))/2;}returnresult;// 返回的result值 = 隨著動畫進度呈先減速后加速的變化趨勢}}

步驟2:設置使用

MainActivity.java

mButton=(Button)findViewById(R.id.Button);// 創(chuàng)建動畫作用對象:此處以Button為例floatcurTranslationX=mButton.getTranslationX();// 獲得當前按鈕的位置ObjectAnimator animator=ObjectAnimator.ofFloat(mButton,"translationX",curTranslationX,300,curTranslationX);// 創(chuàng)建動畫對象 & 設置動畫// 表示的是:// 動畫作用對象是mButton// 動畫作用的對象的屬性是X軸平移// 動畫效果是:從當前位置平移到 x=1500 再平移到初始位置animator.setDuration(5000);animator.setInterpolator(newDecelerateAccelerateInterpolator());// 設置插值器animator.start();// 啟動動畫

效果圖

差值器.gif

6. 與估值器的區(qū)別

估值器和插值器很多人容易混淆,具體區(qū)別如下:

示意圖

7. 總結(jié)

本文對Android動畫中的插值器進行了詳細分析,相信通過本文你已經(jīng)能實現(xiàn)復雜的動畫效果

關于Android動畫的系列文章

動畫的使用,請參考文章:

Android 屬性動畫:這是一篇很詳細的 屬性動畫 總結(jié)&攻略

Android 動畫:手把手教你使用 補間動畫

Android 逐幀動畫:關于 逐幀動畫 的使用都在這里了!

Android 動畫:你真的會使用插值器與估值器嗎?(含詳細實例教學)

自定義View的原理,請參考文章:

(1)自定義View基礎 - 最易懂的自定義View原理系列

(2)自定義View Measure過程 - 最易懂的自定義View原理系列

(3)自定義View Layout過程 - 最易懂的自定義View原理系列

(4)自定義View Draw過程- 最易懂的自定義View原理系列

自定義View的應用,請參考文章:

手把手教你寫一個完整的自定義View

Path類的最全面詳解 - 自定義View應用系列

Canvas類的最全面詳解 - 自定義View應用系列

為什么你的自定義View wrap_content不起作用?

接下來,我我將繼續(xù)對Android動畫進行分析,感興趣的同學可以繼續(xù)關注本人運營的Wechat Public Account:

我想給你們介紹一個與眾不同的Android微信公眾號(福利回贈)

我想邀請您和我一起寫Android(福利回贈)

作者:Carson_Ho

鏈接:http://www.itdecent.cn/p/2f19fe1e3ca1

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容