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

Compose の方法を試す
Jetpack Compose は、Android に推奨される UI ツールキットです。Compose でアニメーションを追加する方法を学びます。

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

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

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

Transition クラスの拡張

カスタム遷移を作成するには、Transition クラスを拡張するクラスをプロジェクトに追加し、次のスニペットに示す関数をオーバーライドします。

KotlinJava
class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

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

}
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() 関数の実装を示しています。

KotlinJava
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
    }

    ...

}
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() 関数の実装を示しています。

KotlinJava
override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}
@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 クラスをご覧ください。プロパティ アニメータの詳細については、プロパティ アニメーションをご覧ください。

カスタム遷移の適用

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