Android

Activity遷移のAnimation

この記事は、下記URLスナップショットです。
https://anolivetree.kibe.la/shared/entries/47646f68-2947-4269-ae2e-e0af9d037879

ActivityのAnimationを指定する方法は3つある

ActivityAからB, BからCを起動するとすると、Animationは以下の8つあることになる。

           Aのanim            Bのanim
           Bのanim            Cのanim
              ↓                ↓
+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+
              ↑                ↑
           Aのanim            Bのanim
           Bのanim            Cのanim

ActivityのAnimationの指定方法には、大きく3つある。
1. ActivityOptions
2. overridePendingTransition
3. activityOpenEnterAnimation等

それぞれが上図のどこに作用するのかが異なるので、ややこしい。

1.ActivityOptionsでの指定

ActivityOptionsでのAnimationにも、二つ方法がある
(正確にはもっとAPIがあるが、調べていないので省略)
- makeSceneTransitionAnimation
- makeCustomAnimation

1.1 makeSceneTransitionAnimation - ApiLevel21(Lollipop)以上

Activityのthemeで、windowEnterTransitionとwindowExitTransition指定して、activityのstart時にmakeSceneTransitionAnimation()で作成したoptionを渡す。

    <style name="Theme1" parent="Theme.AppCompat">
        <item name="android:windowEnterTransition">@android:transition/slide_left</item>
        <item name="android:windowExitTransition">@android:transition/slide_bottom</item>
    </style>

ActivityAからActivityBを起動する。

startActivity(Intent(this, Activity1::class.java),     
  ActivityOptions.makeSceneTransitionAnimation(this@MainActivity).toBundle())

この方法は、以下のように、ActivityBのAnimationを指定できる。
Bを起動するときのoptionなのだが、BからさらにCを起動する時や、Bを閉じるときなどBにかかわるAnimation全てを指定できる。

        B:enterTransition   B:exitTransition
              ↓                ↓
+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+
              ↑                ↑
    B:enterTransitionの逆  B:exitTransitionの逆           

「逆」と書いてあるのは、左からのslide-inなら、逆は左へのslide-outを意味する。

1.2 makeCustomAnimation - ApiLevel16(JellyBean)以上

makeCustomAnimationの引数で、enterResIdとexitResIdを指定する。

startActivity(Intent(this, Activity1::class.java),
  ActivityOptions.makeCustomAnimation(this, R.anim.enterResId, R.anim.exitResId).toBundle());

この方法は、Activityの起動時のAnimationのみを指定する。

         A:exitResId    
         B:enterResId            
              ↓                
+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+

2. overridePendingTransition

startActivity()とfinish()時に使う。どちらのタイミングで使うかで、作用する場所が異なる。

2.1 startActivity時

ActivityAからBをstartActivity()した直後に、overridePendingTransitionを呼ぶ。

startActivity(intent)
overridePendingTransition(R.anim.enterResId, R.anim.exitResId)

ActivityB起動時の、ActivityAとBのAnimationを指定できる。

         A:exitResId    
         B:enterResId            
              ↓                
+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+

2.2 finish時

ActivityBのfinish()でoverridePendingTransitionを呼び出す。

void finish() {
  super.finish()
  overridePendingTransition(R.anim.enterResId, R.anim.exitResId)
}

ActivityB終了時の、ActivityAとBのAnimationを指定できる。

+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+
              ↑ 
         A:enterResId    
         B:exitResId         

3. activityOpenEnterAnimationなど

ActivityBのthemeとして指定したとする。

<style name="ThemeB" parent="Theme.Default">
    <item name="android:windowAnimationStyle">@style/Activity2Anim</item>
</style>
<style name="Activity2Anim">
    <item name="android:activityOpenEnterAnimation">@anim/xxx</item>
    <item name="android:activityOpenExitAnimation">@anim/xxx</item>
    <item name="android:activityCloseExitAnimation">@anim/xxx</item>
    <item name="android:activityCloseEnterAnimation">@anim/xxx</item>
</style>

以下の場所に作用する。

           A:openExit      
           B:openEnter   
              ↓                
+---------+ start +---------+ start +---------+
|ActivityA|------>|ActivityB|------>|ActivityC|
|         |<------|         |<------|         |
+---------+  back +---------+  back +---------+
                                ↑
                            B:closeEnter 
                            C:closeExit

この方法は、ActivityBが表示されるようになる時のAnimationを指定していると考えればよい。つまり、以下の場合のAnimationである。
- ActivityBを起動するとき
- ActivityCを閉じて、ActivityBが再び表示されるとき

優先順位

試した限り、複数指定されていた場合には、優先順位は以下。
1. ActivityOptions
2. overridePendingTransition
3. activityOpenEnterAnimation等

例:
- makeCustomAnimationとstartActivity時のoverridePendingTransitionは、かぶっているので、makeCustomAnimatioが優先される。
- makeCustomAnimationとfinish時のoverridePendingTransitionは、かぶっていないのでどちらの指定も有効。

その他

ActivityAからBを起動するときに、ActivityBがtranslucentだと、ActivityAは消えるわけではないので、ActivityAにexitのAnimationは起こらない。