カスタムの遷移アニメーションを作成する

カスタム遷移を使用すると、組み込みの遷移クラスでは使用できないアニメーションを作成できます。たとえば、テキスト フィールドと入力フィールドの前景色をグレーに変更して、新しい画面でフィールドが無効になっていることを示すカスタム遷移を定義できます。この種の変更は、フィールドが無効であることをユーザーに示すのに役立ちます。

組み込みの遷移タイプの 1 つなどのカスタム遷移は、開始シーンと終了シーンの両方の子ビューにアニメーションを適用します。ただし、組み込みの遷移とは異なり、プロパティ値を取得してアニメーションを生成するコードを用意する必要があります。また、アニメーションのターゲット ビューのサブセットを定義することもできます。

このページでは、プロパティ値をキャプチャし、カスタム遷移を作成するアニメーションを生成する方法について説明します。

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) 関数を実装します。フレームワークは、開始シーンのすべてのビューに対してこの関数を呼び出します。関数の引数は、ビューへの参照と、必要なビュー値を格納できる Map インスタンスを含む TransitionValues オブジェクトです。実装では、こうしたプロパティ値を取得し、地図に保存することでフレームワークに返します。

プロパティ値のキーが他の 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) 関数を 1 回呼び出します。その他に関しては 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() 関数を呼び出す回数は、開始シーンと終了シーンの間に発生する変更によって異なります。

たとえば、カスタム遷移として実装されたフェードアウトまたはフェードイン アニメーションについて考えてみましょう。開始シーンに 5 つのターゲットがあり、そのうち 2 つが終了シーンから削除され、終了シーンに開始シーンの 3 つのターゲットと新しいターゲットがある場合、フレームワークは createAnimator() を 6 回呼び出します。3 つの呼び出しは、両方のシーン オブジェクトに存在するターゲットのフェードアウトとフェードインをアニメーション化しています。さらに 2 つの呼び出しが、終了シーンから離れたターゲットのフェードアウトをアニメーション化しています。1 回の呼び出しで、終了シーンの新しいターゲットのフェードインがアニメーション化されます。

開始シーンと終了シーンの両方に存在するターゲット ビューの場合、フレームワークは startValues 引数と endValues 引数の両方に対して TransitionValues オブジェクトを指定します。開始シーンまたは終了シーンにのみ存在するターゲット ビューの場合、フレームワークは、対応する引数に TransitionValues オブジェクトを提供し、他方の引数に null を提供します。

カスタム遷移を作成するときに createAnimator(ViewGroup, TransitionValues, TransitionValues) 関数を実装するには、取得したビュー プロパティ値を使用して Animator オブジェクトを作成し、フレームワークに返します。実装例については、 CustomTransition サンプルの ChangeColor クラスをご覧ください。プロパティ アニメーターの詳細については、プロパティ アニメーションをご覧ください。

カスタム遷移の適用

カスタム遷移は、組み込み遷移と同様に機能します。遷移を適用するで説明されているように、遷移マネージャーを使用してカスタム遷移を適用できます。