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を渡す。

```xml
    <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を起動する。

```kotlin
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を指定する。

```kotlin
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を呼ぶ。

```kotlin
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を呼び出す。

```java
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として指定したとする。

```xml
<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は起こらない。