なら@はてなブログ

福岡で働くスマートフォンエンジニア(おっさん)のブログ。更新頻度がとにかく低いのが悩み。

ProgressDialogをカスタマイズする

引き続きAndroid。たぶん年内はAndroidどっぷりになりそうなので、記事もそっちに偏りそうです。
 
さて、Androidに限ったことではなく、時間がかかりそうな処理をするときは処理中のお待ちくださいダイアログを出しますね。
Tim Brayも言ってましたが、レスポンスタイムが200msを超えるとユーザはストレスを感じるそうです。昔のWebサービスだと「8秒ルール」とかあったんですが、それに比べるとざっと1/40です。
 
前置きはさておき。
そのProgressDialogですが、デフォルトだといかにもAndroidっぽくて味気ないデザインです。
いちおう処理中画像(ぐるぐる回るやつ、または進捗バー)を自前の画像に差し替えることができますが、基本それだけですね。
f:id:narazoro:20101107011020p:image
 
というわけで、自分でレイアウトを作ってしまうのが一番いいのではないかと。
実用系アプリだとデフォルトで全然問題ないと思うのですが、通常レイアウトをきちんと作りこんでいる場合、ダイアログだけデフォルトで味気ないという状況は避けたいですね。
 
で、一番簡単なやり方と思われるものを。
まずはレイアウトを作ります。
/res/layout/custom_progress_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
<ProgressBar android:id="@+id/ProgressBar01" 
    android:layout_height="wrap_content" android:layout_width="wrap_content" 
    android:indeterminate="true" android:indeterminateDrawable="@drawable/progress_bar" 
    style="?android:attr/progressBarStyle"  />
</LinearLayout>

 
上記ProgressBarのandroid:indeterminateDrawable要素に、自作パラパラアニメを設定しています。
で、そのパラパラアニメの定義例は以下。
/res/drawable/progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
    <item android:drawable="@drawable/b_1" android:duration="200" />
    <item android:drawable="@drawable/b_2" android:duration="200" />
    <item android:drawable="@drawable/b_3" android:duration="200" />
    <item android:drawable="@drawable/b_4" android:duration="200" />
    <item android:drawable="@drawable/b_3" android:duration="200" />
    <item android:drawable="@drawable/b_2" android:duration="200" />
</animation-list>

 
で、プログラム上でどう書くかというと、単にDialog作ってContentViewを設定してやるだけです。
MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.custom_progress_dialog);
    dialog.show();
}

 
で、こうなる。
f:id:narazoro:20101107012000p:image
 
この画像だと全然わかりませんが、いちおう色調がうねうね変わってます。わからんっつーに。
デフォルトより味気ないダイアログになりましたが、今回は「ProgressDialogのレイアウトを自作する」のが目的なのでクオリティは気にしない。
 
と、ここまで書きましたが、これだけだとたぶん不完全です。
なぜかというと、これは普通のダイアログなので、「戻るボタン」でダイアログがキャンセルされるんですね。
なので、そのへんの制御を追加してやるか、キャンセルされた時の処理を入れるかが必要ですね。Dialog.setCancelable(false)あたりですかね。
 
そうそう、意外と明記されてるところが少ないのですが、ProgressBarに指定するdrawableのサイズ、基本は48*48(dp換算)です。で、大きめ画像のスタイル(progressBarStyleLarge)にすると76*76みたいですね。ご参考までに。