這一次讓你徹底了解 Android Tween Animation

1. 什么是 Tween Animation?

通過 Animation 對象在圖像上執(zhí)行一系列的變換而形成的動畫闷愤。

Creates an animation by performing a series of transformations on a single image with an Animation

2. Tween Animation 的作用是什么领跛?

通過上面的定義可知:

Tween Animation 的主要作用是在可視對象上執(zhí)行一系列的變化操作。

舉例來說农渊,就是 Tween Animation 可以改變界面上顯示控件的狀態(tài),如 Button 的顯示弃理、隱藏想罕,ImageView 的尺寸縮放等等屿良。

3. Tween Animation 都包括哪幾類動畫,各類動畫的主要作用是什么惫周?

3.1 Tween Animation 分類

Tween Animation 包括五類動畫尘惧,分別是:

  1. AlphaAnimation
  2. ScaleAnimation
  3. TranslateAnimation
  4. RotateAnimation
  5. AnimationSet

3.2 各類動畫主要作用

  1. AlphaAnimation

主要用于控制 View 的可見性(顯示|隱藏)。

  1. ScaleAnimation

主要用于縮放 View 大小递递。

  1. TranslateAnimation

主要用于移動 View 的位置喷橙。

  1. RotateAnimation

主要用于旋轉(zhuǎn) View。

  1. AnimationSet

某些場景僅靠上面單一類型的動畫是無法實(shí)現(xiàn)的登舞,需要多個(gè)類型的動畫組合才能達(dá)到最終的效果贰逾,此時(shí) AnimationSet 就派上用場了,AnimationSet 的主要作用就是組合各類 Tween Animation菠秒。

4. 如何使用 Tween Animation疙剑?

創(chuàng)建 Tween Animation 的方式共兩種:

  1. XML
  2. CODE

4.1 通過 XML 創(chuàng)建 Tween Animation

4.1.1 通過 XML 創(chuàng)建 AlphaAnimation
4.1.1.1. 語法
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="integer"
    android:fillAfter="true|false"
    android:fillBefore="true|false"
    android:fillEnabled="true|false"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:repeatCount="infinite|integer"
    android:repeatMode="reverse|restart"
    android:fromAlpha="float"
    android:toAlpha="float" />
4.1.1.2. 屬性詳解
屬性 含義 取值范圍
xmlns:android 聲明 XML 布局文件屬性命名空間 http://schemas.android.com/apk/res/android
android:duration 動畫的執(zhí)行時(shí)間 必須大于等于 0,否則程序?qū)?bào)錯(cuò)
android:fillAfter 動畫執(zhí)行完之后是否保留動畫結(jié)束時(shí)的狀態(tài) true 保存践叠,false 不保存(默認(rèn) false)
android:fillBefore 動畫開始執(zhí)行之前言缤,是否應(yīng)用動畫的起始狀態(tài) true 應(yīng)用,false 不應(yīng)用(默認(rèn) true)
android:fillEnabled 該屬性決定了 fillBefore 屬性能否生效 true fillBefore 生效禁灼,false fillBefore 不生效(默認(rèn))
android:interpolator 插值器管挟,決定了動畫的變化率 Android,Custom
android:repeatCount 動畫重復(fù)的次數(shù) 整型數(shù)字弄捕,默認(rèn)為 0僻孝。當(dāng)為負(fù)數(shù)時(shí),表示無限循環(huán)
android:repeatMode 當(dāng)動畫的執(zhí)行次數(shù)大于 1 時(shí)守谓,下一次動畫執(zhí)行的方式 重新開始(默認(rèn))穿铆,反著執(zhí)行
android:fromAlpha 動畫開始時(shí)的透明度 0 透明,1 不透明
android:toAlpha 動畫結(jié)束時(shí)的透明度 0 透明分飞,1 不透明
4.1.1.3. 示例
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@integer/integer_one_thousand_and_two_hundred"
    android:fillAfter="true"
    android:fromAlpha="@integer/integer_one"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toAlpha="@integer/integer_zero" />

最終效果如下:

image
4.1.1.4. 部分屬性解釋

4.1.1.4.1. android:fillAfter

動畫執(zhí)行完之后悴务,是否保留最終的狀態(tài),true 保留,false讯檐,不保留羡疗。

1.android:fillAfter="false"

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@integer/integer_one_thousand_and_two_hundred"
    android:fillAfter="false"
    android:fromAlpha="@fraction/scale_normal"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toAlpha="@integer/integer_zero" />
image
  1. android:fillAfter="true"
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@integer/integer_one_thousand_and_two_hundred"
    android:fillAfter="true"
    android:fromAlpha="@fraction/scale_normal"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toAlpha="@integer/integer_zero" />
image

4.1.1.4.2. android:fillBefore

第二次動畫開始執(zhí)行時(shí),是否從動畫開始的狀態(tài)(fromAlpha)開始執(zhí)行别洪,true 是叨恨,false 不是。

本來想解釋下這個(gè)屬性和 android:fillEnabled 的挖垛,但由于 AlphaAnimation 應(yīng)用此屬性時(shí)痒钝,效果不明顯,所以作罷痢毒。

4.1.2 通過 XML 創(chuàng)建 ScaleAnimation
4.1.2.1. 語法
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="integer"
    android:fillAfter="true|false"
    android:fillBefore="true|false"
    android:fillEnabled="true|false"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:repeatCount="infinite|integer"
    android:repeatMode="reverse|restart"
    android:fromXScale="float"
    android:fromYScale="float" 
    android:toXScale="float"
    android:toYScale="float" 
    android:pivotX="float"
    android:pivotY="float"
    />
4.1.2.2. 屬性詳解
屬性 含義 取值范圍
xmlns:android 聲明 XML 布局文件屬性命名空間 http://schemas.android.com/apk/res/android
android:duration 動畫的執(zhí)行時(shí)間 必須大于等于 0送矩,否則程序?qū)?bào)錯(cuò)
android:fillAfter 動畫執(zhí)行完之后是否保留動畫結(jié)束時(shí)的狀態(tài) true 保存,false 不保存(默認(rèn) false)
android:fillBefore 動畫開始執(zhí)行之前哪替,是否應(yīng)用動畫的起始狀態(tài) true 應(yīng)用栋荸,false 不應(yīng)用(默認(rèn) true)
android:fillEnabled 該屬性決定了 fillBefore 屬性能否生效 true fillBefore 生效,false fillBefore 不生效(默認(rèn))
android:interpolator 插值器凭舶,決定了動畫的變化率 Android晌块,Custom
android:repeatCount 動畫重復(fù)的次數(shù) 整型數(shù)字,默認(rèn)為 0帅霜。當(dāng)為負(fù)數(shù)時(shí)匆背,表示無限循環(huán)
android:repeatMode 當(dāng)動畫的執(zhí)行次數(shù)大于 1 時(shí),下一次動畫執(zhí)行的方式 重新開始(默認(rèn))身冀,反著執(zhí)行
android:fromXScale 動畫開始時(shí)的 X 軸方向上的縮放比例 浮點(diǎn)數(shù)钝尸,默認(rèn)值為 1(大小保持不變)
android:fromYScale 動畫開始時(shí)的 Y 軸方向上的縮放比例 浮點(diǎn)數(shù),默認(rèn)值為 1(大小保持不變)
android:toXScale 動畫結(jié)束時(shí)的 X 軸方向上的縮放比例 浮點(diǎn)數(shù)搂根,默認(rèn)值為 1(大小保持不變)
android:toYScale 動畫結(jié)束時(shí)的 Y 軸方向上的縮放比例 浮點(diǎn)數(shù)蝶怔,默認(rèn)值為 1(大小保持不變)
android:pivotX 動畫執(zhí)行時(shí) X 軸方向上不變的坐標(biāo)點(diǎn)(軸心) 浮點(diǎn)數(shù),默認(rèn)值為縮放對象的左邊
android:pivotY 動畫執(zhí)行時(shí) Y 軸方向上不變的坐標(biāo)點(diǎn)(軸心) 浮點(diǎn)數(shù)兄墅,默認(rèn)值為縮放對象的上邊
4.1.2.3. 示例
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@integer/integer_one_thousand_and_two_hundred"
    android:fillAfter="true"
    android:fromXScale="@fraction/percent_one_hundred"
    android:fromYScale="@fraction/percent_one_hundred"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="@fraction/percent_fifty"
    android:pivotY="@fraction/percent_fifty"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toXScale="@fraction/percent_two_hundred"
    android:toYScale="@fraction/percent_two_hundred" />

最終效果如下:

image
4.1.2.4. 部分屬性解釋

4.1.2.4.1. android:fillAfter

動畫執(zhí)行完之后踢星,是否保留最后的狀態(tài),true 保留隙咸,false沐悦,不保留。

1.android:fillAfter="false"

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="false"
    android:fromXScale="1"
    android:fromYScale="1"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXScale="2"
    android:toYScale="2" />
image

2.android:fillAfter="true"

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXScale="2"
    android:toYScale="2" />
image

4.1.2.4.2. android:fillBefore

第二次動畫開始執(zhí)行時(shí)五督,是否從動畫開始的狀態(tài)(fromXScale藏否,fromYScale)開始執(zhí)行,true 是充包,false 不是副签。

按照開發(fā)文檔的說法遥椿,fillEnabled 屬性將對 fillBefore 屬性有一定的影響,但我在運(yùn)行的時(shí)候淆储,發(fā)現(xiàn)實(shí)際上并沒有什么影響冠场,即 fillBefore 屬性最終有沒有起作用,跟 fillEnabled 是不是 true 沒有關(guān)系(即使當(dāng) fillEnabled = false 時(shí)本砰,fillBefore = true 還是起作用)碴裙。

  1. android:fillAfter="false"
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fromXScale="2"
    android:fromYScale="2"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXScale="4"
    android:toYScale="4" />

當(dāng)?shù)谝淮蝿赢媹?zhí)行完畢之后,再此執(zhí)行動畫的時(shí)候点额,動畫執(zhí)行的目標(biāo)對象會從原始狀態(tài)(閃一下)跳轉(zhuǎn)至 from*Scale舔株,然后從 from*Scale 到 to*Scale。

奈何錄制的 GIF 中剛好丟了這一幀还棱,小老弟载慈,你就用心去體會吧。

image
  1. android:fillAfter="true"
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fillAfter="true"
    android:fillBefore="true"
    android:fromXScale="2"
    android:fromYScale="2"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXScale="4"
    android:toYScale="4" />

當(dāng)?shù)谝淮蝿赢媹?zhí)行完畢之后珍手,再此執(zhí)行動畫的時(shí)候娃肿,動畫執(zhí)行的目標(biāo)對象會直接從 from*Scale 到 to*Scale。

image

4.1.2.4.3. android:pivotX珠十,android:pivotY

動畫執(zhí)行目標(biāo)對象執(zhí)行縮放動畫時(shí),保持不變的坐標(biāo)點(diǎn)凭豪,默認(rèn)為目標(biāo)對象的左上角(動畫執(zhí)行目標(biāo)對象左邊與上邊的焦點(diǎn))焙蹭。

當(dāng) pivotX,pivotY 不為 0 時(shí)嫂伞,最終的 pivotX 和 pivotY 為:

pivotX = left(動畫執(zhí)行目標(biāo)對象左邊絕對坐標(biāo)) + pivotX
pivotY = top(動畫執(zhí)行目標(biāo)對象上邊絕對坐標(biāo)) + pivotY

即最終的軸心點(diǎn)的坐標(biāo)都是相對動畫執(zhí)行目標(biāo)對象左邊和上邊而言的孔厉。

  1. 默認(rèn)值
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXScale="2"
    android:toYScale="2" />
image
  1. android:pivotX="0",android:pivotY="0"
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:pivotX="0"
    android:pivotY="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXScale="2"
    android:toYScale="2" />
image

由于 android:pivotX="0" 和 android:pivotY="0" 均為 0帖努,所以放大動畫的軸心點(diǎn)還在動畫執(zhí)行目標(biāo)對象的左上角撰豺。

  1. android:pivotX="50%",android:pivotY="50%"
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:pivotX="50%"
    android:pivotY="50%"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXScale="2"
    android:toYScale="2" />
image

pivotX拼余、pivotY 分別為動畫執(zhí)行目標(biāo)對象寬污桦、高的一半,所以匙监,放大動畫的軸心點(diǎn)是動畫執(zhí)行目標(biāo)對象的中心凡橱。

  1. android:pivotX="50%p",android:pivotY="50%p"
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:pivotX="50%p"
    android:pivotY="50%p"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXScale="0.1"
    android:toYScale="0.1" />
image

pivotX亭姥、pivotY 分別為動畫執(zhí)行目標(biāo)對象父容器寬稼钩、高的一半,所以达罗,放大動畫的軸心點(diǎn)是:

pivotX = left + parent width/2
pivotY = top + parent height/2

4.1.3 通過 XML 創(chuàng)建 TranslateAnimation
4.1.3.1. 語法
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="integer"
    android:fillAfter="true|false"
    android:fillBefore="true|false"
    android:fillEnabled="true|false"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:repeatCount="infinite|integer"
    android:repeatMode="reverse|restart"
    android:fromXDelta="float"
    android:fromYDelta="float" 
    android:toXDelta="float"
    android:toYDelta="float" 
    />
4.1.3.2. 屬性詳解
屬性 含義 取值范圍
xmlns:android 聲明 XML 布局文件屬性命名空間 http://schemas.android.com/apk/res/android
android:duration 動畫的執(zhí)行時(shí)間 必須大于等于 0坝撑,否則程序?qū)?bào)錯(cuò)
android:fillAfter 動畫執(zhí)行完之后是否保留動畫結(jié)束時(shí)的狀態(tài) true 保存,false 不保存(默認(rèn) false)
android:fillBefore 動畫開始執(zhí)行之前,是否應(yīng)用動畫的起始狀態(tài) true 應(yīng)用巡李,false 不應(yīng)用(默認(rèn) true)
android:fillEnabled 該屬性決定了 fillBefore 屬性能否生效 true fillBefore 生效抚笔,false fillBefore 不生效(默認(rèn))
android:interpolator 插值器,決定了動畫的變化率 Android击儡,Custom
android:repeatCount 動畫重復(fù)的次數(shù) 整型數(shù)字塔沃,默認(rèn)為 0。當(dāng)為負(fù)數(shù)時(shí)阳谍,表示無限循環(huán)
android:repeatMode 當(dāng)動畫的執(zhí)行次數(shù)大于 1 時(shí)蛀柴,下一次動畫執(zhí)行的方式 重新開始(默認(rèn)),反著執(zhí)行
android:fromXDelta 動畫開始時(shí)的 X 軸方向上的起始坐標(biāo) 浮點(diǎn)數(shù)或者百分?jǐn)?shù)矫夯。
當(dāng)為浮點(diǎn)數(shù)時(shí),表示相對于左邊的距離训貌;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后不帶 p制肮,如 5%),表示相對于動畫執(zhí)行目標(biāo)對象寬度的百分之多少递沪;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后帶 p豺鼻,如 5%p),表示相對于動畫執(zhí)行目標(biāo)對象所在父容器寬度的百分之多少款慨;
默認(rèn)值為 0儒飒。
android:fromYDelta 動畫開始時(shí)的 Y 軸方向上的起始坐標(biāo) 浮點(diǎn)數(shù)或者百分?jǐn)?shù)。
當(dāng)為浮點(diǎn)數(shù)時(shí)檩奠,表示相對于上邊的距離桩了;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后不帶 p,如 5%)埠戳,表示相對于動畫執(zhí)行目標(biāo)對象高度的百分之多少井誉;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后帶 p,如 5%p)整胃,表示相對于動畫執(zhí)行目標(biāo)對象所在父容器高度的百分之多少颗圣;
默認(rèn)值為 0。
android:toXDelta 動畫結(jié)束時(shí)的 X 軸方向上的結(jié)束坐標(biāo) 浮點(diǎn)數(shù)或者百分?jǐn)?shù)屁使。
當(dāng)為浮點(diǎn)數(shù)時(shí)欠啤,表示相對于左邊的距離;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后不帶 p屋灌,如 5%)洁段,表示相對于動畫執(zhí)行目標(biāo)對象寬度的百分之多少;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后帶 p共郭,如 5%p)祠丝,表示相對于動畫執(zhí)行目標(biāo)對象所在父容器寬度的百分之多少疾呻;
默認(rèn)值為 0。
android:toYDelta 動畫結(jié)束時(shí)的 Y 軸方向上的結(jié)束坐標(biāo) 浮點(diǎn)數(shù)或者百分?jǐn)?shù)写半。
當(dāng)為浮點(diǎn)數(shù)時(shí)岸蜗,表示相對于上邊的距離;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后不帶 p叠蝇,如 5%)璃岳,表示相對于動畫執(zhí)行目標(biāo)對象高度的百分之多少;
當(dāng)為百分?jǐn)?shù)時(shí)(百分?jǐn)?shù)后帶 p悔捶,如 5%p)瞎嬉,表示相對于動畫執(zhí)行目標(biāo)對象所在父容器高度的百分之多少窃页;
默認(rèn)值為 0。
4.1.3.3. 示例
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@anim/overshoot_interpolator"
    android:toXDelta="0"
    android:toYDelta="50%p" />

最終效果如下:

image
4.1.4 通過 XML 創(chuàng)建 RotateAnimation
4.1.4.1. 語法
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="integer"
    android:fillAfter="true|false"
    android:fillBefore="true|false"
    android:fillEnabled="true|false"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:repeatCount="infinite|integer"
    android:repeatMode="reverse|restart"
    android:fromDegrees="float"
    android:toDegrees="float" 
    android:pivotX="float"
    android:pivotY="float" 
    />
4.1.4.2. 屬性詳解
屬性 含義 取值范圍
xmlns:android 聲明 XML 布局文件屬性命名空間 http://schemas.android.com/apk/res/android
android:duration 動畫的執(zhí)行時(shí)間 必須大于等于 0,否則程序?qū)?bào)錯(cuò)
android:fillAfter 動畫執(zhí)行完之后是否保留動畫結(jié)束時(shí)的狀態(tài) true 保存毁靶,false 不保存(默認(rèn) false)
android:fillBefore 動畫開始執(zhí)行之前蝇更,是否應(yīng)用動畫的起始狀態(tài) true 應(yīng)用然遏,false 不應(yīng)用(默認(rèn) true)
android:fillEnabled 該屬性決定了 fillBefore 屬性能否生效 true fillBefore 生效逊谋,false fillBefore 不生效(默認(rèn))
android:interpolator 插值器,決定了動畫的變化率 Android绢淀,Custom
android:repeatCount 動畫重復(fù)的次數(shù) 整型數(shù)字萤悴,默認(rèn)為 0。當(dāng)為負(fù)數(shù)時(shí)皆的,表示無限循環(huán)
android:repeatMode 當(dāng)動畫的執(zhí)行次數(shù)大于 1 時(shí)覆履,下一次動畫執(zhí)行的方式 重新開始(默認(rèn)),反著執(zhí)行
android:fromDegrees 動畫開始時(shí)的角度 浮點(diǎn)數(shù)祭务,默認(rèn)值為 0
android:toDegrees 動畫結(jié)束時(shí)的角度 浮點(diǎn)數(shù),默認(rèn)值為 0
android:pivotX 動畫執(zhí)行時(shí) X 軸方向上旋轉(zhuǎn)中心(軸心) 浮點(diǎn)數(shù)怪嫌,默認(rèn)值為旋轉(zhuǎn)對象的左邊
android:pivotY 動畫執(zhí)行時(shí) Y 軸方向上旋轉(zhuǎn)中心(軸心) 浮點(diǎn)數(shù)义锥,默認(rèn)值為旋轉(zhuǎn)對象的上邊
4.1.4.2. 示例
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toDegrees="360" />

最終效果如下:

image
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="0"
    android:pivotY="0"
    android:toDegrees="360" />

最終效果如下:

image
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28a6edf2de?w=480&h=853&f=gif&s=172802" width=320 height=560 />

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%p"
    android:pivotY="50%p"
    android:toDegrees="360" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28a9958187?w=480&h=853&f=gif&s=200894" width=320 height=560 />

由上面幾個(gè)示例不難看出,此處的 pivot* 和 ScaleAnimation 動畫中概念完全一樣岩灭,所以拌倍,只要之前理解了這個(gè)概念,在這里也沒有什么困難噪径,直接用就好了柱恤。

4.1.5 通過 XML 創(chuàng)建 AnimationSet
4.1.5.1. 語法
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>
4.1.5.2. 屬性詳解
屬性 含義 取值范圍
xmlns:android 聲明 XML 布局文件屬性命名空間 http://schemas.android.com/apk/res/android
android:interpolator 插值器,決定了動畫的變化率 Android找爱,Custom
android:shareInterpolator 多個(gè)子動畫是否共用插值器 true 共用梗顺,false 不共用(默認(rèn))
4.1.5.3. 示例
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@integer/integer_three_thousand"
    android:fillAfter="true"
    android:shareInterpolator="true">
    <translate
        android:fromXDelta="@integer/integer_zero"
        android:fromYDelta="@integer/integer_zero"
        android:toXDelta="@integer/integer_zero"
        android:toYDelta="@integer/integer_two_hundred" />
    <alpha
        android:fromAlpha="@integer/integer_one"
        android:toAlpha="@fraction/scale_smaller" />
    <rotate
        android:fromDegrees="@integer/integer_zero"
        android:pivotX="@fraction/percent_fifty"
        android:pivotY="@fraction/percent_fifty"
        android:toDegrees="@integer/integer_seven_hundred_and_five" />
</set>

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28ad609dc7?w=480&h=853&f=gif&s=195142" width=320 height=560 />

4.2 通過 CODE 創(chuàng)建 Tween Animation

在 Android 中,大多數(shù)情況下车摄,能通過 XML 實(shí)現(xiàn)的功能幾乎也能通過代碼實(shí)現(xiàn)寺谤,接下來仑鸥,讓我們看下如何通過代碼實(shí)現(xiàn)上面的動畫。

4.2.1 通過 CODE 創(chuàng)建 AlphaAnimation
4.2.1.1. 語法
AlphaAnimation alphaAnimation = new AlphaAnimation(float fromAlpha, float toAlpha);
alphaAnimation.setInterpolator(Interpolator i);
alphaAnimation.setDuration(long durationMillis);
AnimationTarget.startAnimation(alphaAnimation);
4.2.1.2. 示例
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
alphaAnimation.setInterpolator(new AccelerateInterpolator());
alphaAnimation.setFillAfter(mIsSaveAnimationState);
alphaAnimation.setDuration(800);
mTarget.startAnimation(alphaAnimation);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28b0b75780?w=480&h=853&f=gif&s=149441" width=320 height=560 />

4.2.2 通過 CODE 創(chuàng)建 ScaleAnimation
4.2.2.1. 語法
ScaleAnimation scaleAnimation = new ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
scaleAnimation.setInterpolator(Interpolator i);
scaleAnimation.setDuration(long durationMillis);
AnimationTarget.startAnimation(scaleAnimation); 
4.2.2.2. 示例
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 2f, 1f, 2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setInterpolator(new AccelerateInterpolator());
scaleAnimation.setFillAfter(mIsSaveAnimationState);
scaleAnimation.setDuration(800);
mTarget.startAnimation(scaleAnimation);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28bb9e48f1?w=480&h=853&f=gif&s=170655" width=320 height=560 />

4.2.3 通過 CODE 創(chuàng)建 TranslateAnimation
4.2.3.1. 語法
TranslateAnimation translateAnimation = new TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);
translateAnimation.setInterpolator(Interpolator i);
translateAnimation.setDuration(long durationMillis);
AnimationTarget.startAnimation(translateAnimation); 
4.2.3.2. 示例
TranslateAnimation translateAnimation = new TranslateAnimation(0f, 200f, 0f, 200f);
translateAnimation.setInterpolator(new AccelerateInterpolator());
translateAnimation.setFillAfter(mIsSaveAnimationState);
translateAnimation.setDuration(800);
mTarget.startAnimation(translateAnimation);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28c5d484ef?w=480&h=853&f=gif&s=172318" width=320 height=560 />

4.2.4 通過 CODE 創(chuàng)建 RotateAnimation
4.2.4.1. 語法
RotateAnimation rotateAnimation = new RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
rotateAnimation.setInterpolator(Interpolator i);
rotateAnimation.setDuration(long durationMillis);
AnimationTarget.startAnimation(rotateAnimation); 
4.2.4.2. 示例
RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new AccelerateInterpolator());
rotateAnimation.setFillAfter(mIsSaveAnimationState);
rotateAnimation.setDuration(800);
mTarget.startAnimation(rotateAnimation);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28d877c592?w=480&h=853&f=gif&s=152020" width=320 height=560 />

4.2.5 通過 CODE 創(chuàng)建 AnimationSet
4.2.5.1. 語法
AnimationSet animationSet = new AnimationSet(boolean shareInterpolator);
animationSet.addAnimation(Animation a)
...
AnimationTarget.startAnimation(animationSet);
4.2.5.2. 示例
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);
alphaAnimation.setInterpolator(new AccelerateInterpolator());
alphaAnimation.setFillAfter(mIsSaveAnimationState);
alphaAnimation.setDuration(800);

ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 2f, 1f, 2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setInterpolator(new AccelerateInterpolator());
scaleAnimation.setFillAfter(mIsSaveAnimationState);
scaleAnimation.setDuration(800);

RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new AccelerateInterpolator());
rotateAnimation.setFillAfter(mIsSaveAnimationState);
rotateAnimation.setDuration(800);

AnimationSet animationSet = new AnimationSet(false);
animationSet.setFillAfter(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotateAnimation);
mTarget.startAnimation(animationSet);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28d94d721c?w=480&h=853&f=gif&s=874550" width=320 height=560 />

5. 自定義插值器

5.1 什么是插值器变屁,插值器的作用是什么眼俊?

插值器是動畫執(zhí)行速率調(diào)節(jié)器,主要用來控制動畫的變化率粟关。

5.2 常用的插值器有哪些疮胖?

5.2.1 常用插值器匯總
類名 ID 作用
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 加速,減速
AccelerateInterpolator @android:anim/accelerate_interpolator 加速
AnticipateInterpolator @android:anim/anticipate_interpolator 迂回闷板,加速
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 迂回澎灸,加速超出,返回終點(diǎn)
BounceInterpolator @android:anim/bounce_interpolator 彈性
CycleInterpolator @android:anim/cycle_interpolator 變化一圈(正弦曲線)
DecelerateInterpolator @android:anim/decelerate_interpolator 減速
LinearInterpolator @android:anim/linear_interpolator 線性
OvershootInterpolator @android:anim/overshoot_interpolator 加速 超出蛔垢,返回終點(diǎn)
5.2.2 插值器示例
5.2.2.1 AccelerateDecelerateInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28df6df9fc?w=480&h=853&f=gif&s=173127" width=320 height=560 />

5.2.2.2 AccelerateInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/anticipate_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28e568a5be?w=480&h=853&f=gif&s=1556138" width=320 height=560 />

5.2.2.3 AnticipateInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/anticipate_overshoot_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28ea99027f?w=480&h=853&f=gif&s=163203" width=320 height=560 />

5.2.2.4 AnticipateOvershootInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/anticipate_overshoot_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28ee8c6e22?w=480&h=853&f=gif&s=222162" width=320 height=560 />

5.2.2.5 BounceInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/bounce_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f290df8e5e8?w=480&h=853&f=gif&s=217219" width=320 height=560 />

5.2.2.6 CycleInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/cycle_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f2910eebb79?w=480&h=853&f=gif&s=223425" width=320 height=560 />

5.2.2.7 DecelerateInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f29146561ae?w=480&h=853&f=gif&s=195428" width=320 height=560 />

5.2.2.8 LinearInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f291c61763f?w=480&h=853&f=gif&s=1600709" width=320 height=560 />

5.2.2.9 OvershootInterpolator
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/overshoot_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f29235fbb91?w=480&h=853&f=gif&s=185476" width=320 height=560 />

5.3 自定義插值器的方式有哪些击孩?

自定義插值器的方式有兩種:

  1. XML
  2. CODE

5.4 如何自定義插值器

5.4.1. 通過 XML 自定義插值器

通過 XML 自定義插值器的時(shí)候,限制性比較大鹏漆,因?yàn)橄到y(tǒng)只提供了部分插值器的自定義巩梢,如 AccelerateInterpolator,有些插值器是不支持自定義的艺玲,如 AccelerateDecelerateInterpolator括蝠。

接下來,我們就學(xué)習(xí)下如何自定義 AccelerateInterpolator饭聚。

AccelerateInterpolator 中可以自定義的屬性只有:android:factor

android:factor 加速的比率(The acceleration rate)忌警,默認(rèn)值為 1。
  1. 默認(rèn)值
<!-- accelerateInterpolator --> 
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->

<accelerateInterpolator />


<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f28e568a5be?w=480&h=853&f=gif&s=1556138" width=320 height=560 />

  1. 自定義
<!-- custom accelerateInterpolator --> 
<?xml version="1.0" encoding="utf-8"?>
<accelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:factor="4.0" />


<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:fillAfter="true"
    android:fillBefore="false"
    android:fillEnabled="false"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/custom_accelerate_interpolator"
    android:toXDelta="40%p"
    android:toYDelta="0" />

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f2935a6d511?w=480&h=853&f=gif&s=201862" width=320 height=560 />

可以通過 XML 自定義插值器秒梳,除了 AccelerateInterpolator法绵,還有很多,以下是具體列表:

序號 類名
1 AccelerateInterpolator
2 AnticipateInterpolator
3 AnticipateOvershootInterpolator
4 CycleInterpolator
5 DecelerateInterpolator
6 OvershootInterpolator

5.4.2. 通過 CODE 自定義插值器

相對于通過 XML 自定義插值器而言酪碘,通過 CODE 自定義插值器就沒有那么多限制朋譬,可以說唯一能限制你的是你的想象力。

通過代碼自定義插值器其實(shí)也很簡單兴垦,只要實(shí)現(xiàn) Interpolator 接口徙赢,并實(shí)現(xiàn)其中的方法(getInterpolation)就好了。接下來探越,我們先看下 Google 官方是如何實(shí)現(xiàn)插值器的狡赐。

//AccelerateDecelerateInterpolator

package android.view.animation;

import android.content.Context;
import android.util.AttributeSet;

import com.android.internal.view.animation.HasNativeInterpolator;
import com.android.internal.view.animation.NativeInterpolatorFactory;
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;

/**
 * An interpolator where the rate of change starts and ends slowly but
 * accelerates through the middle.
 */
@HasNativeInterpolator
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();
    }
}

上面是 AccelerateDecelerateInterpolator 的具體實(shí)現(xiàn),通過代碼可知钦幔,AccelerateDecelerateInterpolator 是通過余弦函數(shù)實(shí)現(xiàn)的:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f293c97608c?w=1758&h=1080&f=png&s=279186" width=560 height=320 />

上圖中用藍(lán)色框圈出的部分即為 AccelerateDecelerateInterpolator 具體算法實(shí)現(xiàn)枕屉。

明白了上面的道理之后,我們就可以自定義插值器鲤氢。既然 Google 提供了 AccelerateDecelerateInterpolator搀庶,那我們就來實(shí)現(xiàn)一個(gè) DecelerateAccelerateInterpolator拐纱。

由 AccelerateDecelerateInterpolator 應(yīng)用的函數(shù)曲線圖可以發(fā)現(xiàn),在 AccelerateDecelerateInterpolator 中哥倔,加速的過程是函數(shù)曲線斜率逐漸增大的過程秸架,減速的過程是函數(shù)曲線斜率逐漸減小的過程。明白這個(gè)之后咆蒿,如何自定義 DecelerateAccelerateInterpolator 就更明確了:

找一個(gè)開始時(shí)斜率逐漸減小东抹,當(dāng)過了某個(gè)臨界點(diǎn)之后,斜率又逐漸增加的曲線沃测。

大概就是下面這個(gè)樣子:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f293ef334bb?w=1220&h=862&f=png&s=79642" width=560 height=320 />

趕緊回憶下缭黔,在我們初、高中學(xué)習(xí)的過程中有沒有哪個(gè)函數(shù)的曲線跟上面的這個(gè)相似的蒂破?當(dāng)然有馏谨,三次函數(shù)和正切函數(shù)。接下來附迷,我們用正切函數(shù)實(shí)現(xiàn)惧互。

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f294d87c8e3?w=1727&h=1080&f=png&s=256908" width=560 height=320 />

上圖中用藍(lán)色框圈出的部分即是 DecelerateAccelerateInterpolator 實(shí)現(xiàn)的理論基礎(chǔ),接下來喇伯,只需要在對這個(gè)函數(shù)稍作修改即可:

  1. Interpolator 接口中 getInterpolation 方法中 input 的取值范圍為 [0,1]喊儡,而藍(lán)色框圈出的 X 的取值范圍為 [-π/4,π/4],所以稻据,需要將 [0,1] 轉(zhuǎn)換為 [-π/4,π/4]:

π/2 * input - π/4

  1. 正切函數(shù)在 [-π/4,π/4] 取值范圍內(nèi)艾猜,相應(yīng)的函數(shù)值的取值范圍為[-1,1],而 getInterpolation 最終返回值的取值范圍為 [0,1]捻悯,所以匆赃,需要將 [-1,1] 轉(zhuǎn)換為 [0,1]:

(tan(π/2 * input - π/4) + 1)/2

因此最終的實(shí)現(xiàn)為:

public class DecelerateAccelerateInterpolator implements Interpolator {

    @Override
    public float getInterpolation(float input) {
        return (float) ((Math.tan(Math.PI/2 * input - Math.PI/4) + 1)/2);
    }

}
TranslateAnimation translateAnimation = new TranslateAnimation(0f, 0f, 0f, 800f);
translateAnimation.setInterpolator(new DecelerateAccelerateInterpolator());
translateAnimation.setFillAfter(mIsSaveAnimationState);
translateAnimation.setDuration(1800);
mTarget.startAnimation(translateAnimation);

最終效果如下:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f2952c7ffc3?w=480&h=853&f=gif&s=317068" width=320 height=560 />

6. 應(yīng)用實(shí)例

Tween Animation 應(yīng)用場景還是很多的,如控制界面中元素的顯示今缚、隱藏:

<img src="https://user-gold-cdn.xitu.io/2019/3/10/16966f2963c3f09b?w=480&h=853&f=gif&s=207081" width=320 height=560 />

我在這里只是拋磚引玉而已算柳,具體如何使用,還要靠大家發(fā)揮自己的想象力荚斯。

7. 參考文獻(xiàn)

  1. Animation resources
  2. Interpolator
  3. 強(qiáng)大繪圖工具
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埠居,一起剝皮案震驚了整個(gè)濱河市查牌,隨后出現(xiàn)的幾起案子事期,更是在濱河造成了極大的恐慌,老刑警劉巖纸颜,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兽泣,死亡現(xiàn)場離奇詭異,居然都是意外死亡胁孙,警方通過查閱死者的電腦和手機(jī)唠倦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門称鳞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稠鼻,你說我怎么就攤上這事冈止。” “怎么了候齿?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵熙暴,是天一觀的道長。 經(jīng)常有香客問我慌盯,道長周霉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任亚皂,我火速辦了婚禮俱箱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灭必。我一直安慰自己狞谱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布厂财。 她就那樣靜靜地躺著芋簿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪璃饱。 梳的紋絲不亂的頭發(fā)上与斤,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音荚恶,去河邊找鬼撩穿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谒撼,可吹牛的內(nèi)容都是我干的食寡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼廓潜,長吁一口氣:“原來是場噩夢啊……” “哼抵皱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辩蛋,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤呻畸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后悼院,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伤为,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年据途,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绞愚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叙甸。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖位衩,靈堂內(nèi)的尸體忽然破棺而出裆蒸,到底是詐尸還是另有隱情,我是刑警寧澤糖驴,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布光戈,位于F島的核電站,受9級特大地震影響遂赠,放射性物質(zhì)發(fā)生泄漏久妆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一跷睦、第九天 我趴在偏房一處隱蔽的房頂上張望筷弦。 院中可真熱鬧,春花似錦抑诸、人聲如沸烂琴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奸绷。三九已至,卻和暖如春层玲,著一層夾襖步出監(jiān)牢的瞬間号醉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工辛块, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畔派,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓润绵,卻偏偏與公主長得像线椰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子尘盼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚憨愉、低耦合和單一職能的“沖突”實(shí)際上,這兩者...
    彥幀閱讀 3,741評論 0 14
  • 最近我越來越發(fā)現(xiàn)我應(yīng)該改掉拖延的壞毛病笨蚁。 為什么這么說呢睹晒?雖然在一些事情上慢慢改掉了拖延的缺點(diǎn)趟庄,但是在很多問題上括细,...
    成長時(shí)間線閱讀 178評論 0 0
  • 文/她心理 昨夜不知為何贷笛,筆者翻來覆去睡不著,越是睡不著耳朵越是靈敏宙项,窗外本來被當(dāng)作白噪音的蟬鳴也格外刺耳起來乏苦。話...
    她心理閱讀 713評論 2 2
  • 在離去的時(shí)候 我猶豫不決 只想寫首詩作為 餞別的禮物 詩人不談愛情 只堅(jiān)守著一塊陣地 留給最后來敲門的人
    W_Honor閱讀 259評論 0 0
  • 那天是一九九二年的三月八號,婦女節(jié)尤筐,在我們村東仕女河的橋上汇荐,你戴著一副墨鏡,穿著黑色的風(fēng)衣盆繁,迎風(fēng)而立掀淘。風(fēng)掀起你風(fēng)衣...
    善下歸海閱讀 519評論 4 13