概要
LayoutTransitionはViewGroupのレイアウト変更によるアニメーションを自動的にやってくれるクラスです。
ちなみにAPI Level 11から追加されています。
使い方は、LayoutTransitionを生成して、アニメーションさせたいViewGroupにsetLayoutTransition(LayoutTransition)します。
レイアウトファイルで設定する場合は、ViewGroupの属性にandroid:animateLayoutChanges="true"をセットするだけです。
これだけで、ViewGroupに子Viewが追加/削除/表示/非表示された時にアニメーションするようになります。
追加/削除/表示/非表示
デフォルトではViewが追加/削除/表示/非表示された時にアニメーションが実行されます。
こちらがデフォルトのアニメーションです。
Viewを追加する場合は先に他のViewが移動した後に新しいViewがフワッと追加されます。
Viewを削除する場合は逆に消されるViewがフワッと消えてから他のViewが動きます。
Viewを表示(Visible)/非表示(Gone)した場合は、追加/削除されたViewと同じアニメーションになります。
拡大/縮小
では、Viewが拡大/伸縮した場合はどうなるのでしょうか?
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が拡大/縮小された場合でもアニメーションするようになりました。
注意点
追加/削除/表示/非表示で使用したレイアウトは下記になります。
<?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の構成によっては動かない場合があるので、あまりオススメできません。。。
シンプルな画面でコストをかけずにアニメーションを付けたい時などに使う程度ですね。