前言
- 動畫的使用 是
Android
開發(fā)中常用的知識 - 可是動畫的種類繁多、使用復(fù)雜晰甚,每當(dāng)需要 采用自定義動畫 實現(xiàn) 復(fù)雜的動畫效果時,很多開發(fā)者就顯得束手無策
- Android中 補間動畫 & 屬性動畫實現(xiàn)動畫的原理是:
其中,步驟2中的 插值器(Interpolator
)和估值器(TypeEvaluator
)是實現(xiàn) 復(fù)雜動畫效果的關(guān)鍵;本文主要講解 將詳細講解 插值器(Interpolator
)金踪,通過閱讀本文你將能輕松實現(xiàn)復(fù)雜的動畫效果
Carson帶你學(xué)
Android
動畫系列文章:
Carson帶你學(xué)Android:一份全面&詳細的動畫知識學(xué)習(xí)攻略
Carson帶你學(xué)Android:常見的三種動畫類型
Carson帶你學(xué)Android:補間動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:屬性動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:逐幀動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:自定義動畫神器-估值器(含實例教學(xué))
Carson帶你學(xué)Android:自定義動畫神器-插值器(含實例教學(xué))
目錄
1. 簡介
- 定義:Android實現(xiàn)動畫效果中的一個輔助接口
- 作用:設(shè)置 屬性值 從初始值過渡到結(jié)束值 的變化規(guī)律
- 如勻速、加速 & 減速 等等
- 即確定了 動畫效果變化的模式牵敷,如勻速變化胡岔、加速變化 等等
2. 應(yīng)用場景
實現(xiàn)非線性運動的動畫效果。非線性運動是指動畫改變的速率不是一成不變的劣领,如加速姐军、減速運動的動畫效果铁材。
3. 具體使用
插值器在動畫的使用有兩種方式:在XML / Java代碼中設(shè)置:
/*
* 使用方式1:xml
* 主要是設(shè)置插值器屬性 android:interpolator
*/
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
// 通過資源ID設(shè)置插值器
android:interpolator="@android:anim/overshoot_interpolator"
android:duration="3000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="2"
android:toYScale="2" />
>
/*
* 使用方式2:java
*/
// 步驟1:創(chuàng)建 需要設(shè)置動畫的 視圖View
Button mButton = (Button) findViewById(R.id.Button);
// 步驟2:創(chuàng)建透明度動畫的對象 & 設(shè)置動畫效果
Animation alphaAnimation = new AlphaAnimation(1,0);
// 步驟3:創(chuàng)建對應(yīng)的插值器類對象
alphaAnimation.setDuration(3000);
Interpolator overshootInterpolator = new OvershootInterpolator();
// 步驟4:給動畫設(shè)置插值器
alphaAnimation.setInterpolator(overshootInterpolator);
// 步驟5:播放動畫
mButton.startAnimation(alphaAnimation);
- 那么使用插值器時的資源ID是什么呢尖淘?即有哪些類型的插值器可供我們使用呢?
- 插值器分為兩種:Android內(nèi)置默認 & 自定義著觉,下面我將詳細介紹
4. 系統(tǒng)內(nèi)置插值器
4.1 類型
Android
內(nèi)置了 9 種內(nèi)置的插值器實現(xiàn):
4.2 具體使用
- 當(dāng)在XML文件設(shè)置插值器時村生,只需傳入對應(yīng)的插值器資源ID即可
- 當(dāng)在Java代碼設(shè)置插值器時,只需創(chuàng)建對應(yīng)的插值器對象即可
系統(tǒng)默認的插值器是
AccelerateDecelerateInterpolator
饼丘,即先加速后減速
4.3 效果圖
- 使用
Android
內(nèi)置的插值器能滿足大多數(shù)的動畫需求 - 如果上述9個插值器無法滿足需求趁桃,還可以自定義插值器
- 下面將介紹如何自定義插值器(
Interpolator
)
5. 自定義插值器
5.1 本質(zhì)
根據(jù)動畫的進度(0%-100%)計算出當(dāng)前屬性值改變的百分比
5.2 實現(xiàn)方式
自定義插值器需要實現(xiàn)Interpolator或TimeInterpolator接口,并復(fù)寫getInterpolation()方法
- 補間動畫 實現(xiàn)
Interpolator
接口;屬性動畫實現(xiàn)TimeInterpolator
接口TimeInterpolator
接口是屬性動畫中新增的卫病,用于兼容Interpolator
接口油啤,這使得所有過去的Interpolator
實現(xiàn)類都可以直接在屬性動畫使用
Interpolator接口和TimeInterpolator接口說明如下:
// Interpolator接口
public interface Interpolator {
// 內(nèi)部只有一個方法:getInterpolation()
float getInterpolation(float input) {
// 參數(shù)說明
// input值值變化范圍是0-1,且隨著動畫進度(0% - 100% )均勻變化
// 即動畫開始時蟀苛,input值 = 0益咬;動畫結(jié)束時input = 1
// 而中間的值則是隨著動畫的進度(0% - 100%)在0到1之間均勻增加
...// 插值器的計算邏輯
return xxx;
// 返回的值就是用于估值器繼續(xù)計算的fraction值帜平,下面會詳細說明
}
// TimeInterpolator接口
// 同上
public interface TimeInterpolator {
float getInterpolation(float input){
...
};
}
從上面可以看出幽告,自定義插值器的關(guān)鍵在于:對input值根據(jù)動畫的進度(0%-100%)通過邏輯計算從而計算出當(dāng)前屬性值改變的百分比。先來看兩個已經(jīng)實現(xiàn)好的系統(tǒng)內(nèi)置差值器:
- 勻速插值器:
LinearInterpolator
- 先加速再減速 插值器:
AccelerateDecelerateInterpolator
/*
* 勻速差值器:LinearInterpolator
*/
@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
... // 僅貼出關(guān)鍵代碼
public float getInterpolation(float input) {
return input;
// 沒有對input值進行任何邏輯處理裆甩,直接返回
// 即input值 = fraction值
// 因為input值是勻速增加的冗锁,因此fraction值也是勻速增加的,所以動畫的運動情況也是勻速的嗤栓,所以是勻速插值器
}
/*
* 先加速再減速 差值器:AccelerateDecelerateInterpolator
*/
@HasNativeInterpolator
public class AccelerateDecelerateInterpolator implements Interpolator, NativeInterpolatorFactory {
... // 僅貼出關(guān)鍵代碼
public float getInterpolation(float input) {
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值 = 運算后的值 = 先加速后減速
// 所以該差值器是先加速再減速的
}
}
5.3 實例說明
下面,我將寫一個自定義Interpolator
:先減速后加速子房。
/*
* 步驟1:根據(jù)需求實現(xiàn)Interpolator接口
* DecelerateAccelerateInterpolator.java
*/
public class DecelerateAccelerateInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
float result;
if (input <= 0.5) {
result = (float) (Math.sin(Math.PI * input)) / 2;
// 使用正弦函數(shù)來實現(xiàn)先減速后加速的功能,邏輯如下:
// 因為正弦函數(shù)初始弧度變化值非常大就轧,剛好和余弦函數(shù)是相反的
// 隨著弧度的增加证杭,正弦函數(shù)的變化值也會逐漸變小解愤,這樣也就實現(xiàn)了減速的效果送讲。
// 當(dāng)弧度大于π/2之后,整個過程相反了過來哼鬓,現(xiàn)在正弦函數(shù)的弧度變化值非常小异希,漸漸隨著弧度繼續(xù)增加宠互,變化值越來越大,弧度到π時結(jié)束搏色,這樣從0過度到π频轿,也就實現(xiàn)了先減速后加速的效果
} else {
result = (float) (2 - Math.sin(Math.PI * input)) / 2;
}
return result;
// 返回的result值 = 隨著動畫進度呈先減速后加速的變化趨勢
}
}
/*
* 步驟2:設(shè)置使用
* MainActivity.java
*/
// 1. 創(chuàng)建動畫作用對象:此處以Button為例
mButton = (Button) findViewById(R.id.Button);
// 2. 獲得當(dāng)前按鈕的位置
float curTranslationX = mButton.getTranslationX();
// 3. 創(chuàng)建動畫對象 & 設(shè)置動畫
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "translationX", curTranslationX, 300,curTranslationX);
// 表示的是:
// 動畫作用對象是mButton
// 動畫作用的對象的屬性是X軸平移
// 動畫效果是:從當(dāng)前位置平移到 x=1500 再平移到初始位置
// 4. 設(shè)置步驟1中設(shè)置好的插值器:先減速后加速
animator.setInterpolator(new DecelerateAccelerateInterpolator());
// 5. 啟動動畫
animator.start();
效果圖
6. 與估值器的區(qū)別
估值器和插值器很多人容易混淆航邢,具體區(qū)別如下:
7. 總結(jié)
- 本文對
Android
動畫中的插值器進行了詳細分析膳殷,相信通過本文你已經(jīng)能實現(xiàn)復(fù)雜的動畫效果 - Carson帶你學(xué)
Android
動畫系列文章:
Carson帶你學(xué)Android:一份全面&詳細的動畫知識學(xué)習(xí)攻略
Carson帶你學(xué)Android:常見的三種動畫類型
Carson帶你學(xué)Android:補間動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:屬性動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:逐幀動畫學(xué)習(xí)教程
Carson帶你學(xué)Android:自定義動畫神器-估值器(含實例教學(xué))
Carson帶你學(xué)Android:自定義動畫神器-插值器(含實例教學(xué))
歡迎關(guān)注Carson_Ho的簡書
不定期分享關(guān)于安卓開發(fā)的干貨薄榛,追求短勒极、平辱匿、快炫彩,但卻不缺深度媒楼。