【Android】AlertDialogの「OK」ボタンを入力状態に応じて動的に無効化する

Android

前回の記事ではダイアログにテキスト入力を追加する方法を解説しましたが、今回はさらに一歩踏み込んで、**「未入力のときはOKボタンを押せないようにする(バリデーション)」**機能を実装してみましょう。

ユーザーの誤操作を防ぎ、アプリの堅牢性を高めるために非常に重要なテクニックです。

1. 実装のポイント

AlertDialogのボタンを制御するには、以下のステップが必要です。

  1. builder.create() および show() を先に呼び出す(表示後でないとボタンを取得できないため)。
  2. dialog.getButton() でOKボタンのインスタンスを取得する。
  3. EditTextTextWatcher をセットし、文字数を監視する。

2. サンプルコード

Java

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        showValidatedDialog();
    }

    private void showValidatedDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("名前を入力してください");

        // EditTextの作成と余白設定
        final EditText input = new EditText(this);
        input.setHint("例:山田 太郎");
        
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(50, 20, 50, 0);
        layout.addView(input);
        builder.setView(layout);

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // OKボタンが押されたときの処理
            }
        });

        builder.setNegativeButton("キャンセル", (dialog, which) -> dialog.cancel());

        // 1. まずはダイアログを作成して表示する
        final AlertDialog dialog = builder.create();
        dialog.show();

        // 2. 表示後にOKボタンを取得し、初期状態を無効にする
        final Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
        okButton.setEnabled(false); 

        // 3. TextWatcherで入力内容をリアルタイム監視
        input.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // 文字数が1文字以上のときだけOKボタンを有効化
                boolean isInputEmpty = s.toString().trim().isEmpty();
                okButton.setEnabled(!isInputEmpty);
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });
    }
}

3. コードの解説

なぜ dialog.show() の後で設定するのか?

AlertDialog.Builder の段階では、まだボタンの View 自体が生成されていません。そのため、getButton() を呼ぶ前に必ず show() を実行して、画面上にダイアログを構築させる必要があります。

trim() による空白チェック

サンプルでは s.toString().trim().isEmpty() を使用しています。これにより、**「スペース(空白)だけ入力されている」**状態も未入力として扱い、より確実に不正な入力を防ぐことができます。


まとめ

TextWatcher を使うことで、ユーザーの入力に合わせた柔軟なUI制御が可能になります。 「必須項目が埋まるまで次に進ませない」というUIは、ユーザーフレンドリーなアプリ制作の第一歩です。ぜひ活用してみてください。

コメント