建立自訂的轉場動畫

您可以使用自訂轉場效果,建立無法透過任何內建轉換類別提供的動畫。舉例來說,您可以定義自訂轉場效果,將文字和輸入欄位的前景顏色轉成灰色,表示這些欄位在新畫面中已停用。這類變更可協助使用者看到您停用的欄位。

自訂轉場效果 (例如其中一種內建轉換類型) 會將動畫套用至開始場景和結束場景的子檢視畫面。不過,與內建轉換類型不同的是,您必須提供擷取屬性值並產生動畫的程式碼。您可能也想為動畫定義目標檢視畫面的子集。

本頁說明如何擷取屬性值及產生動畫來建立自訂轉場效果。

擴充 Transition 類別

如要建立自訂轉場效果,請在專案中新增可擴充 Transition 類別的類別,並覆寫以下程式碼片段中顯示的函式:

Kotlin

class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {}

}

Java

public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

以下各節說明如何覆寫這些函式。

擷取檢視屬性值

轉場動畫會使用屬性動畫總覽中所述的屬性動畫系統。屬性動畫會在指定時間範圍內將檢視畫面屬性從起始值變更為結束值,因此架構需要屬性的起始值和結束值以建構動畫。

然而,屬性動畫通常只需要所有檢視區塊屬性值的一小部分。舉例來說,顏色動畫需要顏色屬性值,而移動動畫則需要位置屬性值。由於動畫所需的屬性值專屬於轉換,因此轉換架構並不會為轉換提供所有屬性值。而是會叫用回呼函式,讓轉換作業僅擷取所需屬性值,並將其儲存在架構中。

擷取起始值

如要將起始檢視值傳遞至架構,請實作 captureStartValues(transitionValues) 函式。架構會在起始場景中的每個檢視畫面呼叫此函式。函式引數是 TransitionValues 物件,包含檢視畫面的參照和 Map 例項,您可以在其中儲存所需的檢視畫面值。在您的實作中,擷取這些屬性值,然後儲存在對應中以傳回架構。

為確保屬性值的鍵不會與其他 TransitionValues 鍵衝突,請採用以下命名配置:

package_name:transition_name:property_name

下列程式碼片段說明 captureStartValues() 函式的實作方式:

Kotlin

class CustomTransition : Transition() {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"

    override fun captureStartValues(transitionValues: TransitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues)
    }

    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private fun captureValues(transitionValues: TransitionValues) {
        // Get a reference to the view
        val view = transitionValues.view
        // Store its background property in the values map
        transitionValues.values[PROPNAME_BACKGROUND] = view.background
    }

    ...

}

Java

public class CustomTransition extends Transition {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private static final String PROPNAME_BACKGROUND =
            "com.example.android.customtransition:CustomTransition:background";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues);
    }


    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private void captureValues(TransitionValues transitionValues) {
        // Get a reference to the view
        View view = transitionValues.view;
        // Store its background property in the values map
        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
    }
    ...
}

擷取結束值

架構會針對結束場景中的每個目標檢視畫面呼叫一次 captureEndValues(TransitionValues) 函式。在所有其他方面,captureEndValues() 的運作方式與 captureStartValues() 相同。

下列程式碼片段顯示 captureEndValues() 函式的實作:

Kotlin

override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}

Java

@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

在此範例中,captureStartValues()captureEndValues() 函式會叫用 captureValues() 以擷取和儲存值。captureValues() 擷取的檢視畫面屬性相同,但開始和結束場景的值不同。這個架構會針對檢視畫面的開始和結束狀態分別維護地圖。

建立自訂動畫

如要為起始場景中的檢視畫面狀態與結束場景中的狀態變更建立動畫效果,請覆寫 createAnimator() 函式來提供動畫。架構呼叫這個函式時,會傳入場景根層級檢視畫面和 TransitionValues 物件 (其中包含您擷取的起始值和結束值)。

架構呼叫 createAnimator() 函式的次數取決於啟動場景和結束場景之間的變更。

舉例來說,考慮以淡出或淡入效果實作做為自訂轉場效果。如果起始場景有五個目標,其中兩項是從結束場景中移除,而結束場景的三個目標從起始場景中移除,再加上新目標,則架構會呼叫 createAnimator() 六次。其中三個呼叫以動畫方式呈現,讓兩個場景物件中的目標淡出及淡入。另外兩次呼叫,以動畫效果從結束場景中移除目標。其中一個呼叫會在結束場景中顯示新目標的淡入動畫。

對於起始和結束場景中的目標檢視畫面,架構會為 startValuesendValues 引數提供 TransitionValues 物件。如果目標檢視畫面只存在於起始或結束場景中,架構會提供對應引數的 TransitionValues 物件,並為另一個引數提供 null

如要在建立自訂轉場時實作 createAnimator(ViewGroup, TransitionValues, TransitionValues) 函式,請使用擷取的檢視屬性值建立 Animator 物件,並將其傳回架構。如需實作範例,請參閱 CustomTransition 範例中的 ChangeColor 類別。如要進一步瞭解屬性動畫,請參閱「屬性動畫」。

套用自訂轉場效果

自訂轉場效果的運作方式與內建轉場效果相同。您可以按照「套用轉換」一節所述,使用轉換管理員套用自訂轉場效果。