Transition サポート ライブラリ 26.0.0

# Transition サポート ライブラリ

Transition サポート ライブラリは、API レベル 19 KitKat で追加された Transition API を API レベル 14 Ice Cream Sandwich までバックポートするライブラリです。2017 年 7 月に公開されたバージョン 26.0.0 で大幅にパワーアップしました。具体的には Lollipop 以降に導入された様々な API を追加し、また Transition XML もサポートしました。

```groovy:build.gradle
dependencies {
    compile "com.android.support:transition:26.0.0"
}
```

## Lollipop で追加された API

### 新しい Transition タイプ

これまで利用できた KitKat の Transition タイプ (ChangeBounds, Fade, AutoTransition, TransitionSet) に加えて、Lollipop で追加された新しい Transition タイプがサポート ライブラリでも利用できます。


<dl>
<dt>ChangeClipBounds</dt>
<dd>ViewCompat.setClipBounds をアニメーション</dd>
<dt>ChangeImageTransform</dt>
<dd>ImageView.setScaleType などをアニメーション</dd>
<dt>ChangeTransform</dt>
<dd>View.setTranslationX, Y などをアニメーション</dd>
<dt>Explode</dt>
<dd>View.setVisibility をアニメーション - 中心点から離れるように画面外に移動</dd>
<dt>Slide</dt>
<dd>View.setVisibility をアニメーション - 画面の端に移動</dd>
<dt>ChangeScroll</dt>
<dd>スクロールをアニメーション</dd>
</dl>

例えばボタンを押すたびに対象の View が画面の端から出てきたり引っ込んだりするようなアニメーションをするなら新しく追加された `Slide` を使ってできます。

```kotlin:MainActivity.kt
companion object {
    val SLIDE = Slide(Gravity.END)
}

// (略)

    // toggle はボタン
    toggle.setOnClickListener {
        // root は親 ViewGroup
        TransitionManager.beginDelayedTransition(root, SLIDE)
        // box が対象の View
        box.visibility = if (box.visibility == View.VISIBLE) View.INVISIBLE else View.VISIBLE
    }
```

自前で `View.animate()` などを使って実装することもできるでしょうが、Transition API なら一行です。ボタンを連打しても対象の View は途中の状態からうまくアニメーションします。

### Transition の機能

<dl>
<dt>PathMotion</dt>
<dd>View の移動やサイズ変更など二次元的な動きをするアニメーションについて、X 軸と Y 軸を指定された曲線に沿って変化させる</dd>
<dt>TransitionPropagation</dt>
<dd>Transition を複数の View に同時に適用するとき、View ごとに開始するタイミングをずらす</dd>
<dt>Epicenter</dt>
<dd>Transition の中心点を指定する</dd>
</dl>

例えばボタンを押すたびに対象の View の Gravity を切り替え、その移動を円弧に従ってアニメーションするならこのようにできます。

```kotlin:MainActivity.kt
companion object {
    val GRAVITY1 = Gravity.START or Gravity.TOP
    val GRAVITY2 = Gravity.END or Gravity.BOTTOM
    val CHANGE_BOUNDS = ChangeBounds().apply {
        pathMotion = ArcMotion()
        interpolator = FastOutSlowInInterpolator()
    }
}

// (略)

    toggle.setOnClickListener {
        TransitionManager.beginDelayedTransition(root, CHANGE_BOUNDS)
        val lp = box.layoutParams as FrameLayout.LayoutParams
        lp.gravity = if (lp.gravity == GRAVITY1) GRAVITY2 else GRAVITY1
        box.layoutParams = lp
    }
```

クリックリスナーの中では Transition API を呼び出して LayoutParams を書き換えているだけです。

## Transition XML

これまでサポート ライブラリで利用することができなかった Transition 用のリソース XMLが利用できるようになりました。

Transition XML は例えば以下のようなものです。

```xml:res/transition/my_transition.xml
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <fade android:fadingMode="fade_out" />
    <changeBounds />
    <fade android:fadingMode="fade_in" />
</transitionSet>
```

コードから以下のようにしてインスタンス化できます。

```kotlin:MainActivity.kt
val myTransition = TransitionInflater.from(this).inflateTransition(R.transition.my_transition)
```

ここで登場する `android:fadingMode` という属性は KitKat で追加されたものです。通常サポート ライブラリでバックポートされるこのような XML 属性を利用する場合
 `android:` ではなく `app:` と書き換えなければならないことが多いのですが、Transition XML では `android:` のまま利用できます。すでにある Transition XML を書き換える必要は一切ありません。その代わり、build.gradle に以下の記述が必要です。

```groovy:build.gradle
android {
    // (略)
    aaptOptions {
        additionalParameters "--no-version-transitions"
    }
}
```

その他、バグ報告やフィードバックは [Google Issue Tracker](https://issuetracker.google.com/issues/new?component=192731&template=842428) にお願いします。