LoginSignup
3
3

overridePendingTransitionがDeprecatedになったのでoverrideActivityTransitionに置き換える

Last updated at Posted at 2023-11-12

overridePendingTransitionがDeprecatedになったけど、SDK_INTで分岐させてoverridePendingTransitionを単純にoverrideActivityTransitionに置き変えればよい訳ではない。というお話

前置き

長らくActivity遷移アニメーションを指定するために使っていた Activity#overridePendingTransition がDeprecatedになってしまいました。

This method was deprecated in API level 34.
Use overrideActivityTransition(int, int, int)} instead.

ということで overrideActivityTransition に置き換えなさいということですね。
overrideActivityTransition の説明には以下のように書かれています。

For example, if we want to customize the opening transition when launching Activity B which gets started from Activity A, we should call this method inside B's onCreate with overrideType = OVERRIDE_TRANSITION_OPEN because the Activity B will on top of the task. And if we want to customize the closing transition when finishing Activity B and back to Activity A, since B is still is above A, we should call this method in Activity B with overrideType = OVERRIDE_TRANSITION_CLOSE.

ようするに、AからBに遷移するときのアニメーションと、BからAに戻るときのアニメーションはBで指定しなさい。ってことらしいです。AからBに遷移するときのアニメーションはBのonCreateで指定しなさい。ってことです。
つまり、overridePendingTransitionを単純にoverrideActivityTransitionに置き変えればよい訳ではないってことみたいです。

ちょっと検証してみましょう。

検証

遷移アニメーションが分かりやすいように以下のようなアニメーションリソースを定義しておきます。

アニメーションリソース
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="-100%"
    android:toXDelta="0%"
    />
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="100%"
    android:toXDelta="0%"
    />
slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0%"
    android:toXDelta="-100%"
    />
slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0%"
    android:toXDelta="100%"
    />

duration を1000=1秒と長めに設定して、違いが分かりやすいようにしています。

overridePendingTransition

MainActivityとMainActivity2の間で遷移させるとして、overridePendingTransitionは以下のように使いますね。

MainActivity.kt
binding.button.setOnClickListener {
    startActivity(Intent(this, MainActivity2::class.java))
    overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
}
MainActivity2.kt
binding.button.setOnClickListener {
    finish()
    overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
}

こうすることで、MainActivityからMainActivity2の遷移とその戻りのアニメーションをカスタマイズすることができます。これはAndroid 14でもまだ使えますね。

デフォルト overridePendingTransition

単純に置き換え

先に説明したとおり、単純な置き換えはできないということでしたが、置き換えた場合どうなるのかを見てみましょう。

MainActivity.kt
binding.button.setOnClickListener {
    startActivity(Intent(this, MainActivity2::class.java))
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        overrideActivityTransition(
            Activity.OVERRIDE_TRANSITION_OPEN, R.anim.slide_in_right, R.anim.slide_out_left
        )
    } else {
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
    }
}
MainActivity2.kt
binding.button.setOnClickListener {
    finish()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        overrideActivityTransition(
            Activity.OVERRIDE_TRANSITION_CLOSE, R.anim.slide_in_left, R.anim.slide_out_right
        )
    } else {
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
    }
}

そうすると以下のように、finishのあととはいえ、MainActivity2の方で指定したクローズのアニメーションは適用されていますが、MainActivityの方で指定した、オープンのアニメーションは適用されませんでした。

overridePendingTransition overrideActivityTransition

正しい対応方法

上に表示されるActivityのonCreateでOPEN/CLOSEとも指定するのが良さそうです。
CLOSEも指定するのは、overridePendingTransitionと違って先に指定しておけるためであることと、後述しますが、予測型「戻る」ジェスチャーの挙動に影響するためです。
複数回呼び出した場合は上書きになるため、閉じ方によってアニメーションを変更したい場合はその直前に指定すれば変更できますし、clearOverrideActivityTransitionという指定をクリアするメソッドも用意されています。

MainActivity.kt
binding.button.setOnClickListener {
    startActivity(Intent(this, MainActivity2::class.java))
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
    }
}
MainActivity2.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        overrideActivityTransition(
            Activity.OVERRIDE_TRANSITION_OPEN, R.anim.slide_in_right, R.anim.slide_out_left
        )
        overrideActivityTransition(
            Activity.OVERRIDE_TRANSITION_CLOSE, R.anim.slide_in_left, R.anim.slide_out_right
        )
    }
    val binding = ActivityMain2Binding.inflate(layoutInflater)
    setContentView(binding.root)
    binding.button.setOnClickListener {
        finish()
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
        }
    }
}
overridePendingTransition overrideActivityTransition

予測型「戻る」ジェスチャーの挙動

overrideActivityTransitionOVERRIDE_TRANSITION_CLOSEの指定をすると、Android 14から導入された、予測型「戻る」ジェスチャーでの動きにも適用されます。このアニメーションはfinishの前に実行されるものなので、このタイミングではなく、あらかじめ設定しておく必要があります。

overridePendingTransition overrideActivityTransition

まとめ

予測型「戻る」ジェスチャーのアニメーションの指定もできるようになっているので、overrideActivityTransitionへの置き換えを進めていきたいですね。ただ、単純な置き換えはできないので、minSdkVersionを34にできるまでは、処理の分岐をあちこちで書かないといけないのが悩みどころですね。


overrideActivityTransitionが使えない場合

これで万事解決かと思いきや、overrideActivityTransitionが通用しない場合がありました。
Activityのテーマで、android:windowShowWallpaperandroid:windowIsTranslucenttrueにしている場合です。

themes.xml
<style name="Theme.MyApplication2" parent="Base.Theme.MyApplication">
    <item name="android:windowShowWallpaper">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

この場合、以下のように、overridePendingTransitionでは指定できるのに、overrideActivityTransitionでは指定とは異なるアニメーションになってしまいます。(予測型「戻る」ジェスチャーには適用されるみたいですが……)

overridePendingTransition overrideActivityTransition

ActivityOptionを使う方法

開始についてはstartActivityのActivityOptionについてはまだDeprecatedになっていませんので、以下のようにするとこで開始アニメーションを変更できます。

MainActivity.kt
val options = ActivityOptions.makeCustomAnimation(this, R.anim.slide_in_right, R.anim.slide_out_left).toBundle()
startActivity(Intent(this, MainActivity2::class.java), options)

しかし、閉じる方のアニメーションはこのような方法では指定できないようです。

wallpaperXXXXAnimation を指定する方法

オープンクローズ両方を指定したい場合は、以下のようにstyleを作成し

styles.xml
<style name="anim">
    <item name="android:wallpaperOpenEnterAnimation">@anim/slide_in_right</item>
    <item name="android:wallpaperOpenExitAnimation">@anim/slide_out_left</item>
    <item name="android:wallpaperCloseEnterAnimation">@anim/slide_in_left</item>
    <item name="android:wallpaperCloseExitAnimation">@anim/slide_out_right</item>
</style>

window.setWindowAnimationsでActivityで指定します。

MainActivity2.kt
window.setWindowAnimations(R.style.anim)

こうすることで、同様のアニメーションを実行することができるようになりました。

以上です。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3