ダイアログは永遠に(2) - ダイアログとアクティビティ
今回は、ダイアログクラス全般についての話題を。
も~っと素直に,も~っと自由に、そのままのDialogクラスでいて
AlertDialogクラスではなく、AlertDialogクラスのスーパクラスであるDialogクラス そのもの使って、ダイアログを表示する事もできる。
前回、AlertDialogによって実装した「カスタムダイアログを表示」のサンプルをDialogクラスを使って実現してみる。
プログラムは以下のようになる。
ダイアログのレイアウト用のxmlファイルは、前回と同じものをそのまま使っている。
AlertDialogと異なり、setViewメソッドのかわりにsetContentViewメソッドを使って、 アクティビティのようにコンテンツビューに、Viewオブジェクトを指定する。
AlertDialogクラスは、 安直に使う事ができるダイアログであったが、ビルダークラスを使う事が前提となっていて、 AlertDialogクラスのインスタンスを生成するには、ビルダークラスを仲介する必要があった。
Dialogクラスには、ビルダークラスは存在せず、直接インスタンスを生成する。
しかし、DialogクラスにはAlertDialogクラスのように、あらかじめ用意されているボタン等のウィジェットを、簡単に表示させる機能は存在しない。
あくまでも、コンテンツビューを介してウィジェットを表示する事になる。
当然、コンテンツビューへのViewオブジェクトの指定には、レイアウトファイルだけではなくコードを使って直接記述したViewオブジェクトを指定する事もできる。
アクティビティより愛をこめて - ダイアログとアクティビティとの熱い関係
アクティビティクラスには、ダイアログの状態を自動的に管理する仕組みが用意されている。
アクティビティに結びつけられた、複数のダイアログを管理するために、ユーザ定義のダイアログの識別子(ID)が使われる。
ダイアログを操作するには、ダイアログのIDを引数にとる以下の3つのメソッドがある。
- showDialog
ダイアログを表示するにはshowDialogメソッドを使う。 - dismissDialog
ダイアログを廃棄するにはdismissDialogメソッドを使う。 - removeDialog
ダイアログを再表示する必要が無い場合に、ダイアログを廃棄するにはremoveDialogメソッドを使う。
dismissDialogメソッドとの動作の違いについては後述する。
上記のダイアログを操作するメソッドを実行する事で、ダイアログの状態の変化に応じて、以下の3つイベントメソッドのどれかが呼び出される。
- onCreateDialog
最初にダイアログを表示される前に各IDごとに1回だけ呼び出される。
このメソッド内で、アクティビティが管理する、ダイアログの生成をおこなうコードを記述する必要がある。 - onPrepareDialog
ダイアログが表示されるたびに、表示の前に必要な処理を実行するために呼び出される。 ここに、表示前にに必要な処理を記述する。 - onDismiss
ダイアログの破棄時に、必要な処理がある場合はここに記述する。
ダイアログに、setOnDismissListenerを使ってイベントリスナーを指定しなければ、呼び出されない。
onCreateDialogメソッド内で生成されたDialogオブジェクトが、アクティビティ内にを結びつけられて、管理されることになる。
以下のプログラムの例を示す。(ちょっと長いコードになってしまったが)
このプログラムは、2つチェックボックスのどちらか選択してボタンを押す事で、チェック項目に対応した2つのダイアログを操作するメソッドを実行する。
このプログラムを実行すると、以下のような画面が表示される。
各イベントメソッドでは、どのようなタイミングでイベントが呼ばれるのかを調査するため、Logを出力するコードを挿入している。
このログの出力より、dismissDialogメソッドとremoveDialogメソッドの違いをみてみると、 dismissDialogメソッドを実行した後に、showDialogメソッドを使ってダイアログを再度表示させても、 onCreateDialogメソッドは発生しないが、removeDialogメソッドを実行した後に、 showDialogメソッドを使ってダイアログを再度表示させると、onCreateDialogメソッドが発生している。
onCreateDialog() メソッド外で生成したDialogオブジェクトも、 setOwnerActivity メソッドを使うと、アクティビティに結びつけて管理する事ができるような事が ドキュメント には書いてあるが、 これをどのように使うのかについてはよくわからない。
Ok,キャンセルボタンの処理と
dismissメソッドとcancelメソッドと戻るボタンにより発生するイベントの違い
Dialogクラスには、ダイアログを閉じるのに dismissメソッドとcancelメソッドが使える。
その他にも、戻るボタンでダイアログを閉じる事もできる。
また、ダイアログ閉じる時に発生するイベントとして、onDismissイベントとonCancelイベントとがある。
次のプログラムを使って、ダイアログを閉じる時にどのイベントが発生するか調べてみた。
結果は、以下のようにdismissメソッドを使った場合のみ、onCancelイベントが発生しない。
- dismissメソッド
onDismissイベントのみ発生。 - cancelメソッド
onCancelイベントの後にonDismissイベントが発生。 - 戻るボタン
onCancelイベントの後にonDismissイベントが発生。(cancelメソッドと同じ)
通常、戻るボタンの押下は、キャンセルボタンと同意と考えられるので、これは理にかなっていると思われる。
この事を利用して、34,58、64行のコメントの位置にOk,キャンセル時の処理を実装と都合が良い。
些細な事であるが、onDismissイベントとonCancelイベントの発生するタイミングについて、 憶えておいたほうが良いかな。