今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

ダイアログの表示とボタンを押されたあとの動作のコードの書き方

ダイアログのidについて

ダイアログを表示したいときは、まずActivity#showDialog(int id)を呼ぶ。
そうすると、Activity#onCreateDialog(int id)が呼ばれる(最初だけ)。
詳しく調べたわけではないけどたぶんActivity毎にAlertDialogのインスタンスをHashMapか何かで管理していて、idで取り出せるようにしてるっぽい。
なにかのイベントでダイアログを表示したい時に、同じidだけど異なるメッセージをダイアログに表示しようとしても、二度目からはActivity#onCreateDialog(int id)は呼ばれない。前回表示したときのメッセージのままでダイアログが表示されてしまう。
つまり、メッセージを変えたいときは異なるidを用意する必要がある。

public class HogeActivity extends Actiity {
    public static final int DIALOG_ERROR1 = 1;
    public static final int DIALOG_ERROR2 = 2;
    // とにかく全部を書く 

    @Override
    public Dialog onCreateDialog(int id) {
        switch (id) {
        case DIALOG_ERROR1:
            return createError1Dialog();
        case DIALOG_ERROR2:
            return createError2Dialog();
        // 別々にダイアログインスタンスを生成する
        default:
            throw new IllegalArgumentException("invalid dialog id. : " + id);
    }
}

ダイアログ内の入力フィールドについて

ダイアログの画面から入力フィールドを取得するときは、引数のDialogInterfaceから取り出す。EditTextなどをActivityのインスタンス変数などで保持していると、コードの書き方によっては、ダイアログの画面内のEditTextのインスタンスと、Activityで保持しているインスタンスが異なり、入力内容を取得できなかったりする。

自分がバグッた状況は、

イベント発生

ダイアログインスタンス生成

showDialog()

onCreateDialog()で生成したダイアログインスタンスを返す(1回だけしか呼ばれない)

ダイアログが表示される

入力してボタン押す

onClick(DialogInterface dialog, int witch)が呼ばれる

入力内容を取得できない
みたいな感じ。実際は、1回目に生成したインスタンスが使いまわされるのに、2回目以降もインスタンスを生成して、そちらのEditTextのインスタンスを参照していたため、入力値を取得できてなかった。

正しい入力フィールドのインスタンスを取得するには、こうすればバッチリ。

    @Override
    public void onClick(DialogInterface dialog, int witch) {
        if (whitch == DialogInterface.BUTTON_NEGATIVE) return;
        EditText field = (EditText)((AlertDialog)dialog).findViewById(R.id.hoge);
        String s = field.getText().toString();
        // あーだこーだ
    }