LoginSignup
20
14

More than 5 years have passed since last update.

LayoutTransition:お手軽にアニメーション

Last updated at Posted at 2017-11-13

概要

LayoutTransitionはViewGroupのレイアウト変更によるアニメーションを自動的にやってくれるクラスです。
ちなみにAPI Level 11から追加されています。
使い方は、LayoutTransitionを生成して、アニメーションさせたいViewGroupにsetLayoutTransition(LayoutTransition)します。
レイアウトファイルで設定する場合は、ViewGroupの属性にandroid:animateLayoutChanges="true"をセットするだけです。
これだけで、ViewGroupに子Viewが追加/削除/表示/非表示された時にアニメーションするようになります。

追加/削除/表示/非表示

デフォルトではViewが追加/削除/表示/非表示された時にアニメーションが実行されます。
こちらがデフォルトのアニメーションです。

ezgif-5-3c902af560.gif

Viewを追加する場合は先に他のViewが移動した後に新しいViewがフワッと追加されます。
Viewを削除する場合は逆に消されるViewがフワッと消えてから他のViewが動きます。
Viewを表示(Visible)/非表示(Gone)した場合は、追加/削除されたViewと同じアニメーションになります。

拡大/縮小

では、Viewが拡大/伸縮した場合はどうなるのでしょうか?

ezgif-5-c3e1e0c736.gif

Viewが拡大/縮小されてもアニメーションしないですね。
拡大/縮小させるFrameLayout(@id/text_layout)にandroid:animateLayoutChanges="true"をセットしているのにも関わらずアニメーションされませんでした。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/text_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:animateLayoutChanges="true"
        android:background="#ff6f6f">

        <TextView
            android:id="@+id/text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp" />
    </FrameLayout>

    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="submit" />

</LinearLayout>

上述したとおり、デフォルトでは追加/削除/表示/非表示された時のみしかアニメーションが実行されないからです。
拡大/縮小のアニメーションを設定するためにはenableTransitionType()CHANGINGをセットします。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    ((ViewGroup) findViewById(R.id.text_layout)).getLayoutTransition()
            .enableTransitionType(LayoutTransition.CHANGING);
}

enableTransitionType()はAPI Level 16から追加された事に注意してください。

これでViewが拡大/縮小された場合でもアニメーションするようになりました。

ezgif-5-616171dffc.gif

注意点

追加/削除/表示/非表示で使用したレイアウトは下記になります。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/add_button"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_margin="3dp"
            android:layout_weight="1"
            android:background="#ffc6c6"
            android:gravity="center"
            android:text="Add" />

            ・・・・・

    </LinearLayout>

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:animateLayoutChanges="true"
        android:orientation="vertical" />

    <FrameLayout
        android:id="@+id/bottom_view"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:animateLayoutChanges="true"
        android:background="#37e4ae">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Item"
            android:textColor="@android:color/white" />
    </FrameLayout>

</LinearLayout>

android:animateLayoutChanges="true" がルートのViewGroupとFrameLayout(@id/bottom_view)に設定されていますね。
ルートのViewGroupにandroid:animateLayoutChanges="true"を設定しなかった場合はVisible/Goneのアニメーションはしなくなります。
ADD/REMOVEボタンをタップした時にViewが追加/削除されるLinearLayout(@id/container)はルートのViewGroupにandroid:animateLayoutChanges="true"を設定しなくてもアニメーションします。

どういった時に必要なのかは分かりませんが、アニメーションしなかった場合はルートのViewGroupにandroid:animateLayoutChanges="true"を設定してみてください。

ドキュメントにもありますが、ネストされた複数の階層でViewをアニメーションをさせると機能しない場合があるようです。

おわりに

ViewGroupの属性にセットするだけでアニメーションをつけられるお手軽感はありますが、アニメーションが不安定だったり、Viewの構成によっては動かない場合があるので、あまりオススメできません。。。
シンプルな画面でコストをかけずにアニメーションを付けたい時などに使う程度ですね。

20
14
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
20
14