Home > android > Dialogをアニメーションさせる方法

Dialogをアニメーションさせる方法

前のエントリではActivityを表示するアニメーションについて述べました。
今回はDialogを表示する際のアニメーションについて考えてみます。

Dialog
普通

なにも設定せずにDialogを表示するとこんな感じです。

ゴール

今回はこんな感じのちょっと有機を感じる動きにしてみます。

エミュレータのキャプチャなのでコマ落ちで分かりにくいかもしれませんが、
開く(閉じる)動作に助走を付けている感じです。

残念なおしらせ

残念ながら、今回はソースコードを修正する必要があります。
以前のActivityのように、XMLだけ編集すれば統一的に動作を変更できれば良かったのですが、
Dialogの動作を統一的に変更する方法が見つけられませんでした。
ご存知の方はゼヒ教えて下さい。

Dialogの呼出し

とてもシンプルな方法でDialogを表示させます。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final EditText textET = (EditText)findViewById(R.id.text_et);
    Button dlgBtn = (Button)findViewById(R.id.toast_btn);
    dlgBtn.setOnClickListener(new OnClickListener(){
        public void onClick(View v) {
            String text = textET.getText().toString();
            showDialog(text); //ここでダイアログを表示する
        }});
}
 
private void showDialog(String msg) {
    if (mDialog == null) {
        mDialog = new CustomDialog(this);//特別なDialog
        mDialog.setContentView(R.layout.dialog);
        mDialog.setTitle(R.string.app_name);
        TextView msgTV = (TextView)mDialog.findViewById(R.id.msg_tv);
        msgTV.setText(msg);
        Button clsBtn = (Button)mDialog.findViewById(R.id.close_btn);
        clsBtn.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                mDialog.dismiss();
            }});
    }
    mDialog.show();//ダイアログの表示
}

ActivityのボタンをタップしたらshowDialogメソッドが呼出されてDialogを表示します。
このメソッドで作るDialogがCustomDialogという、独自のクラスになります。

Custom Dialog

独自Dialogと言っても特別なことは殆どしません。アニメーションの調整などは
プログラマではなくUXに長けた人に任せた方がクォリティを高められると思います。
そのためにも、ソースコードにパラメータをできるだけ持たせないようにしたいという思想です。
CustomDialogはこんな感じです。

public class CustomDialog extends Dialog {
    public CustomDialog(Context context) {
        super(context, R.style.Theme_CustomDialog);//ここだけ変わった
    }
}

なんともシンプルです。
コンストラクタの引数だけ変えました。
R.tyle.Theme_CustomDialogです。
こんなクラス作らず、外から指定すればイイじゃないかという話もありますが、
大きなソースコードで複数のDialogを使うようなプログラムだと、
毎回変数を引数に渡すのも面倒なので、作っておきました。

さて、問題は引数に渡したR.style.Theme_CustomDialogが何者かです。

テーマを定義する
res/values/themes.xml

Activityと同様にDialogにもデフォルトのテーマが存在します。
今回はダイアログの表示動作を変更した新たなテーマを定義します。
それがR.style.Theme_CustomDialogです。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Theme.CustomDialog" parent="android:style/Theme.Dialog">
        <item name="android:windowAnimationStyle">@style/Animation.CustomDialog</item>
    </style>
</resources>

DialogのデフォルトテーマがTheme.Dialogなので、これを親として独自のテーマを拡張しています。
ここではwindowAnimationStyle要素だけを変更しています。
その動作はstyles.xmlの中で定義します。

res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Animation.CustomDialog" parent="android:Animation.Dialog">
        <item name="android:windowEnterAnimation">@anim/dialog_enter</item>
        <item name="android:windowExitAnimation">@anim/dialog_exit</item>
    </style>
</resources>

Animation.CustomDialogの中ではダイアログが開くときのwindowEnterAnimationと
ダイアログが閉じるときのwindowExitAnimationの2つを指定します。
各要素の値はアニメーションを指定するxmlファイルです。

res/anim/dialog_{enter|exit}.xml

まずはダイアログが開くときのアニメーションを定義します。

<?xml version="1.0" encoding="utf-8"?>
<scale	xmlns:android="http://schemas.android.com/apk/res/android"
		android:interpolator="@anim/overshoot"
		android:fromXScale="0.0" android:toXScale="1.0"
		android:fromYScale="0.0" android:toYScale="1.0"
		android:pivotX="50%" android:pivotY="50%" android:duration="300"/>

0から1の大きさまで300msかけて広がるというアニメーションです。
広がる方法はinterpolatorで指定しています。今回はovershoot.xmlというファイルで定義しています。

<?xml version="1.0" encoding="utf-8"?>
<overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 
              android:tension="3.0"/>

overshootInterpolatorといは、目的値を一度通り越して、戻ってくるとい変換関数です。
tensionという属性値は通り越し具合を指定しています。何も指定しないと2.0ですので、
今回は分かりやすさのため大袈裟に通り越します。

同様にして、ダイアログが閉じる時のアニメーションも定義します。

<?xml version="1.0" encoding="utf-8"?>
<scale	xmlns:android="http://schemas.android.com/apk/res/android"
		android:interpolator="@anim/anticipate"
		android:fromXScale="1.0" android:toXScale="0.0"
		android:fromYScale="1.0" android:toYScale="0.0"
		android:pivotX="50%" android:pivotY="50%" android:duration="300"/>

interpolatorにanticipateを指定しています。anticipate.xmlは下記のように定義しています。

<?xml version="1.0" encoding="utf-8"?>
<anticipateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
               android:tension="3.0"/>

anticipateInterpolatorとは、スタート値から目的値方向とは逆方向に一旦移動した後、目的値に到達するという変換関数です。

overshootもanticipateもAndroid1.6から導入されたAPIです。

言い訳

1.6縛りになるのが嫌だったので、独自のinterpolatorを作って、ここで指定したのですが、
何故か読み込み時にエラーになり適用できませんでした。
こちらも良い方法をご存知の方はぜひ教えて下さい。

ソースコード

いつものようにソースコードを公開します。
自由にお楽しみ下さい。Android1.6以上での動作を確認しています。
CustomDialog.zip

おわりに

今回はDialogの動作を変更しました。
こういう有機的な動きは見ていて気持ち良いものです。
もし、もっと興味を持ったならTweenerをお調べになると良いと思います。
私のブログでもActionScriptで随分お世話になりました(例1例2)。
デザイン部の開発チームでは、Tweenerを参考にinterpolatorを作るってのもアリかもしれませんね。

このエントリをはてなブックマークに登録 Deliciousにブックマーク
関連のありそうなエントリ

Comments:0

Comment Form
Remember personal info

*
To prove that you're not a bot, enter this code
Anti-Spam Image

Trackbacks:2

Trackback URL for this entry
http://www.adamrocker.com/blog/291/how-to-animate-the-android-dialog.html/trackback/
Listed below are links to weblogs that reference
Dialogをアニメーションさせる方法 from throw Life
pingback from Twitter Trackbacks for throw Life - Dialogをアニメーションさせる方法 [adamrocker.com] on Topsy.com 10-01-29 (金) 22:49

[…] Topsy Retweet Button var topsy_style = “small”; var topsy_order = “count,retweet,badge”; var topsy_url = “http://www.adamrocker.com/blog/291/how-to-animate-the-android-dialog.html”; Add Topsy Retweet Button to your Blog or Web Site. WordPress  Web Sites […]

pingback from How to make the dialog becomes bigger gradually instead of instantly : Android Community - For Application Development 13-04-25 (木) 17:30

[…] It is possible to animate a Dialog. Please refer to this tutorial. Sorry it is in japanese. And since I can read japanese I assume you can read japanese. […]

Home > android > Dialogをアニメーションさせる方法

Author
Search
Feeds
Meta

Return to page top