DialogFragmentを使ったダイアログの表示【Android/Kotlin】



Androidの公式ドキュメントよりダイアログの表示サンプルを試してみた。ドキュメントではJavaで記述されているがここではKotlinに書き直して実装した。

なお、本プロジェクトはGithubリポジトリへ公開してある。







ダイアログの基本


Androidでダイアログを表示させるにはDialogクラスを継承したAlertDialogを使う。Activityでインスタンス生成するのではなく、DialogFragmentクラスを経由してインスタンスを生成する。DialogFragmentクラスはFragmentを継承しているのでActivityのライフサイクルと同期することができる。また、DialogFragmentでカプセル化されるのでActivityが肥大化せず、ダイアログを管理しやすくなる。

実際にサンプルを見たほうが分かりやすいので、次ではCancelDoneの2つのボタンを実装したシンプルなダイアログを作っていく。





シンプルなダイアログ




DialogFragmentクラスを継承したSimpleDialogFragmentクラスを作成する。onCreateDialogメソッドをオーバーライドしてその中でAlertDialogのインスタンスをビルダーで生成している。



Activityからは次のようにして呼び出すことができる。以降、ダイアログの呼び出しはすべてこの方法で行う。






リストメニューのダイアログ




先程のシンプルなダイアログではsetPositiveButtonなどでボタンを追加したが、リスト表示ではsetItemsメソッドを使って配列をセットする。ここではsetMessageを実装してしまうとリストが表示されなくなるので注意したい。



setItemsメソッドの第二引数へはクリックされたときの処理をラムダ式を渡すことになっている。このラムダ式はOnClickListenerインタフェースで定義されている。ラムダ式内の第二引数(which)にはクリックされた配列のインデックスが渡される。






チェックボックスのダイアログ




チェックボックスタイプのダイアログにはsetMultiChoiceItemsを使う。setMultiChoiceItemsの第二引数には、予めチェックしておきたい場所をbooleanArray型で渡すことができる。





ラジオボタンのダイアログ




ラジオボタンタイプのダイアログではsetSingleChoiceItemsを使う。setSingleChoiceItemsの第二引数にデフォルトでチェックしておきたいインデックスをint型で渡すことができる。






カスタムレイアウトのダイアログ(ログイン入力)




ダイアログのレイアウトを自由にカスタマイズすることができる。ここでは公式ドキュメントにならってログイン入力用のダイアログを実装した。

まずは表示したいレイアウトファイルdialog_signin.xmlを次のように作成する。




そしてこのレイアウトをDialogFragmentクラス内でinflaterinflateする。つまりdialog_signinレイアウトを元にしたViewを生成する。丁寧にプログラムを追えば何も難しいことはない。







ダイアログからアクティビティへコールバックする




最後にアクティビティへコールバック可能なダイアログを作成する。インタフェースを使ってコールバックを実装することでActivityとダイアログを疎結合にすることができ、キレイなコードで管理することができる。ここではシンプルなダイアログのプログラムを元に改造した。




上記のプログラムを詳しく見ていこう。

まず、コールバック用のインターフェースNoticeDialogListerを、DialogFragmentを継承したNoticeDialogFragmentクラス内に作成する。





このインタフェースはダイアログを呼び出すホストつまりMainActivityへ実装することになる。



onAttachMainActivity(ここではContextになっているが)をNoticeDialogListerへキャストしている。ホストのActivityNoticeDialogListerインタフェースが実装されていなければ例外がスローされるようになっている。このことで実装のし忘れを避けることができるのだ。



そしてダイアログのボタンクリックイベント内でNoticeDialogListerのメソッドを実行しているのがわかるだろう。



このコールバックの実装パターンは、iOS開発では頻繁に行われるデリゲートでのコールバックとよく似ている。Objective-C/SwiftのprotocolがJava/Kotlinのinterfaceに対応しているのだ。またiOSでは強参照を避けるためにweakを指定するが、AndroidでのFragmentを通した実装ではその必要がないようである。ここは確かなことは言えないのだが、ダイアログを終了するとDialogFragmentonDestroyonDetachが呼ばれることを確認しているので問題ないということにしたい。

基本からしっかり身につくAndroidアプリ開発入門

圧倒的な多数のユーザーが使っているヤフーのアプリ。その制作の最前線にいる黒帯エンジニアが、ユーザーが使いやすいアプリの大切な基本をしっかりと解説します。

KindleAmazon

Kotlinプログラミング

Kotlinは、Javaとの相互運用を可能にし、Android OSでGoogleがフルサポートする静的型プログラミング言語です。この言語は、Javaだけでは十全ではない(Javaだけでは実装に手間がかかりすぎる)、軽量かつ豊かな表現形式や、他言語ではすでに実装されている最新の機能を盛り込んでいます。

KindleAmazon




【おまけ】英語雑学




Dialog / Dialogue の語源は log(話す) から来ている。logはギリシャ語で「話す」や「単語」「会話」を意味する。
dia(間で) + log(話す) であるのでつまりは「対話」「意見交換」といった意味となる。

英英辞書では (a) written conversation in a book or play と書かれているように、本やゲームにおいての書かれた対話となる。

また log には log house というようにという意味もある。
文字を木に書いていた歴史からもlogが対話(書かれた)などの意味をもつのは自然なことではないだろうか。

The mayor tried to maintain a dialogue with the citizens.

He's not very good at writing dialogue.


logを語源とする単語は他にもたくさん存在する。

  • catalog (カタログ)
  • logo (ロゴ)
  • logic (論理)
  • apology (謝罪)
  • prologue (序幕)
  • epilogue (結びの言葉)
  • monologue (独白)

アプリのDialogもユーザーとの対話ということなので、一方的なスパムアラートにならないように表示のやり方には十分気を配りたいところである。

アカオアルミ DON アルミフライパン 27cm アルミニウム合金、ハンドル(アルミダイキャスト) 日本製 AHL24027

普通アルミ材に対し耐食性・耐摩耗性にすぐれている。プロの酷使に耐久性を発揮。伝導アルミは鉄やステンレスに比べ熱伝導がよい。熱ムラがないので料理の仕上がりがよく、煮る、蒸す、わかす、焼く道具として適している。

Amazon

あなたにおすすめ