Android 補間動畫

AnRFDev發表於2021-08-11

補間動畫:通過使用 Animation 對單張圖片執行一系列轉換來建立動畫。

在 XML 中定義的動畫,用於對圖形執行旋轉、淡出、移動和拉伸等轉換。

動畫檔案放在res/anim/,該檔名將用作資源 ID。

移動示例

先用一個例子建立直觀的認識。新建一個動畫xml,實現從左到右的效果。
move_hor_1.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:toXDelta="-100%" />

    <translate
        android:duration="400"
        android:startOffset="200"
        android:toXDelta="100%" />
</set>

要使用這個動畫,需要用到AnimationUtils.loadAnimation(getContext(), R.anim.move_hor_1);來載入動畫。得到物件mAnimation
交給View.startAnimation(mAnimation);來啟動。

上面的動畫例子效果圖

仔細看一下動畫xml裡的內容

  • set裡有2個translate
  • translate表示移動動作
    • duration是這個動作的執行時長(毫秒)
    • toXDelta表示橫行移動
    • startOffset表示動畫開始執行多久後再執行這個動作

實際上,第二個translate週期是400毫秒,它“等了”200毫米才開始執行。
把View從左邊移動到了右邊。

縮放示例

除了位移,還可以執行縮放效果。

可以看到示例種先放大再縮小回去。主要是用了android:repeatMode="reverse"android:repeatCount="1"

完整動畫xml如下

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="600"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toXScale="1.35"
        android:toYScale="1.35" />
</set>

scale裡面我們遇到了幾個元素pivotXrepeatCountrepeatMode

  • android:pivotX 在物件縮放時要保持不變的 X 座標;pivotY同理。
  • android:repeatCount 動畫的重複次數。設為 "-1" 表示無限次重複,也可設為正整數。
    • 例如,值 "1" 表示動畫在初次播放後重復播放一次,因此動畫總共播放兩次。預設值為 "0",表示不重複。
  • android:repeatMode 動畫播放到結尾處的行為。android:repeatCount 必須設定為正整數或 "-1",該屬性才有效。
    • 設定為 "reverse" 可讓動畫在每次迭代時反向播放,
    • 設定為 "repeat" 則可讓動畫每次從頭開始迴圈播放。

多個動畫元素的例子

一個<set>集合裡可以包含多個元素。

錄製gif的出來發現快結束時總有一個抖動,是錄製的問題。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <rotate
        android:duration="500"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />

    <translate
        android:duration="500"
        android:fromXDelta="0%"
        android:toXDelta="50%" />

    <alpha
        android:duration="500"
        android:fromAlpha="1"
        android:toAlpha="0.5" />

    <set
        android:interpolator="@android:anim/decelerate_interpolator"
        android:startOffset="500">
        <rotate
            android:duration="400"
            android:fromDegrees="360"
            android:pivotX="100%"
            android:pivotY="50%"
            android:toDegrees="0" />

        <translate
            android:duration="400"
            android:fromXDelta="0%"
            android:toXDelta="-50%" />

        <alpha
            android:duration="400"
            android:fromAlpha="0.5"
            android:toAlpha="1" />

    </set>
</set>

<set>裡放置著多個元素,可以把<set>放進<set>裡。
我們分成出發和回來兩個動作

出發:

第一個<rotate>是從自己的中心位置開始。
<translate>水平向右走了50%。

回來:

後面<rotate>pivotX需要考慮到出發時水平移動了50%,因此pivotX取值100%。

<translate>從0%走到-50%即可。

動畫xml元素

下面總結一下各個屬性

<?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>

set

容納其他動畫元素( 或其他 元素)的容器。代表 AnimatorSet
可以放置多個動畫元素,組合在一起。每個set可定義自己的 ordering 屬性。

  • android:interpolator 插值器資源。 要應用於動畫的 Interpolator。 該值必須是對指定插值器的資源的引用(而不是插值器類名稱)。可使用平臺提供的預設插值器資源,也可建立自己的插值器資源。
  • android:shareInterpolator 布林值。如果要在所有子元素中共用同一插值器,則為“true”。

alpha

淡入或淡出動畫。對應AlphaAnimation類。

  • android:fromAlpha 浮點數。起始不透明度偏移,0.0 表示透明,1.0 表示不透明。
  • android:toAlpha 浮點數。結束不透明度偏移,0.0 表示透明,1.0 表示不透明。

scale

縮放動畫,調整大小的動畫;對應ScaleAnimation
指定 pivotXpivotY,來指定View向外(或向內)擴充套件的中心點。
例如,如果這兩個值為 0、0(左上角),則所有擴充套件均向右下方向進行。

  • android:fromXScale 浮點數。起始 X 尺寸偏移,其中 1.0 表示不變。
  • android:toXScale 浮點數。結束 X 尺寸偏移,其中 1.0 表示不變。
  • android:fromYScale 浮點數。起始 Y 尺寸偏移,其中 1.0 表示不變。
  • android:toYScale 浮點數。結束 Y 尺寸偏移,其中 1.0 表示不變。
  • android:pivotX 浮點數。在物件縮放時要保持不變的 X 座標。
  • android:pivotY 浮點數。在物件縮放時要保持不變的 Y 座標。

translate

移動動畫。垂直或水平移動。或者水平和垂直移動一起。對應TranslateAnimation
支援採用以下三種格式之一的以下屬性:從 -100 到 100 的以“%”結尾的值,表示相對於自身的百分比;從 -100 到 100 的以“%p”結尾的值,表示相對於其父項的百分比;不帶字尾的浮點值,表示絕對值。

屬性:

  • android:fromXDelta float或百分比。起始 X 偏移。表示方式:相對於正常位置的畫素數(例如 "5"),相對於元素寬度的百分比(例如 "5%"),或相對於父項寬度的百分比(例如 "5%p")。
  • android:toXDelta float或百分比。結束 X 偏移。表示方式同fromXDelta
  • android:fromYDelta float或百分比。起始 Y 偏移。表示方式:相對於正常位置的畫素數(例如 "5"),相對於元素高度的百分比(例如 "5%"),或相對於父項高度的百分比(例如 "5%p")。
  • android:toYDelta float或百分比。結束 Y 偏移。表示方式同fromYDelta

rotate

旋轉動畫。對應RotateAnimation

屬性:

  • android:fromDegrees浮點數。起始角度位置,以度為單位。
  • android:toDegrees浮點數。結束角度位置,以度為單位。
  • android:pivotXfloat或百分比。旋轉中心的 X 座標。表示方式:相對於物件左邊緣的畫素數(例如 "5"),相對於物件左邊緣的百分比(例如 "5%"),或相對於父級容器左邊緣的百分比(例如 "5%p")。
  • android:pivotYfloat或百分比。旋轉中心的 Y 座標。表示方式:相對於物件上邊緣的畫素數(例如 "5"),相對於物件上邊緣的百分比(例如 "5%"),或相對於父級容器上邊緣的百分比(例如 "5%p")。

參考

相關文章