アラートダイアログ(AlertDialog)のカスタマイズ - Android

AlertDialogをカスタマイズして任意のコントロールをダイアログ内に配置する手順を紹介します。

シンプルなAlertDialogのカスタマイズ

AlertDialogレイアウトXMLファイルの追加と編集

カスタマイズのためのレイアウトファイルを追加します。

[Project Explorer]にてプロジェクトノード内の"res/layout"ノードを選択し右クリックのポップアップメニューを表示します。メニューの[New]の[Other...]を選択します。


[New]ダイアログボックスが表示されます。一覧から"Android"カテゴリの"Android XML Layout File"を選択します。選択後[Next]ボタンを押します。


LayoutXMLファイルの設定画面が表示されます。[File]欄にファイル名を入力します。今回は"dialog"と入力しました。[RootElement]は"LinerLayout"を選択しました。選択後[Next]ボタンを押します。


"Choose Configuration Folder"の画面が表示されます。今回は何もせず[Finish]ボタンを押します。


LayoutXMLファイルが作成されデザイナのウィンドウが表示されます。


EditTextコントロールを一つ配置します。


レイアウトファイルのコードは以下になります。

dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >

        <requestFocus />
    </EditText>

</LinearLayout>

UI

MainActivityのレイアウトファイルを編集します。今回はボタンを1つ配置します。配置したボタンの"On Click"プロパティに"button1_click"を設定しました。

コード

以下のコードを記述します。

MainActivity.java

package com.iPentec.customdialog;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.LayoutInflater;
import android.app.AlertDialog;
import android.content.DialogInterface;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  public void button1_click(View view){
    LayoutInflater factory = LayoutInflater.from(this);
    final View inputView = factory.inflate(R.layout.dialog, null);
    
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setIcon(android.R.drawable.ic_dialog_alert);
    builder.setTitle("カスタムダイアログ");
    builder.setView(inputView);
    
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int whichButton) {
          
      }
    });

    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      }
    });

    AlertDialog dialog = builder.create();
    dialog.show();

  }
}

解説

button1_click
  LayoutInflater factory = LayoutInflater.from(this);
  final View inputView = factory.inflate(R.layout.dialog, null);
にて、LayoutInflatorの取得をし、LayoutInflatorを用いてレイアウトXMLを読み込みViewを取得します。リソースIDはXML レイアウトファイルが"dialog.xml"であるため、"R.layout.dialog"となります。

  AlertDialog.Builder builder = new AlertDialog.Builder(this);
  builder.setIcon(android.R.drawable.ic_dialog_alert);
  builder.setTitle("カスタムダイアログ");
  builder.setView(inputView);
    
  builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int whichButton) {        
    }
  });

  builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    }
  });
AlertDialog.Builderのインスタンスを作成し、AlertDialogの設定をします。詳しくはこちらの記事を参照してください。
builder.setView(inputView);
により、AlertDialogにレイアウトXML(dialog.xml)で定義したViewを埋め込みます。

  AlertDialog dialog = builder.create();
  dialog.show();
AlertDialog.Builderの設定情報をもとにAlertDialogを表示します。

実行結果

プロジェクトを実行します。下図の画面が表示されます。


ボタンをタップするとAlertDialogが表示されます。上部にdialog.xmlのレイアウトファイルの内容が表示されていることが確認できます。


AlertDialog内のEditTextコントロールに文字の入力もできます。

カスタムダイアログのコントロールへのアクセス

カスタムダイアログ中のコントロールにアクセスするコードを紹介します。

UI

MainActivity

メインのアクティビティにはButtonとTextViewを配置します。

dialog.xml

カスタムダイアログに組み込むレイアウトファイルを作成しデザインします。TextViewとEditTextコントロールを配置しました。

コード

以下のコードを記述します。
package com.iPentec.customdialog;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.LayoutInflater;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
  private View inputView;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  public void button1_click(View view){
    //showDialog(CustomViewCallback)
    LayoutInflater factory = LayoutInflater.from(this);
    inputView = factory.inflate(R.layout.dialog, null);
    
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setIcon(android.R.drawable.ic_dialog_alert);
    builder.setTitle("カスタムダイアログ");
    builder.setView(inputView);
    
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int whichButton) {
        if (inputView != null){
          EditText et = (EditText)inputView.findViewById(R.id.editText1);
          String text = et.getText().toString();
          
          TextView textView2 = (TextView)findViewById(R.id.textView2);
          textView2.setText(text);
        }
      }
    });
    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      }
    });
    AlertDialog dialog = builder.create();
    dialog.show();
  }
}

解説

ダイアログの表示部分は先に紹介したコードと同じです。

  builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int whichButton) {
      if (inputView != null){
        EditText et = (EditText)inputView.findViewById(R.id.editText1);
        String text = et.getText().toString();
          
        TextView textView2 = (TextView)findViewById(R.id.textView2);
        textView2.setText(text);
      }
    }
  });
上記のダイアログボックスのClickハンドラが追加のコードになります。

  if (inputView != null){
    EditText et = (EditText)inputView.findViewById(R.id.editText1);
    String text = et.getText().toString();
          
    TextView textView2 = (TextView)findViewById(R.id.textView2);
    textView2.setText(text);
  }
ダイアログに埋め込んだinputViewがnullかチェックし、nullでなければ処理をします。inputViewのfindViewById()メソッドを呼び出し、ダイアログ内に表示されているEditTextコントロールオブジェクトを取得します。オブジェクト取得後getText()メソッドを呼び出しEditTextに入力されている文字列を取り出します。
続いてthis.findViewById()メソッド(上記コードではthisは省略されています。)を呼び出し、MainActivityのTextViewオブジェクトを取得します。オブジェクトを取得しsetText()メソッドを呼び出し、ダイアログに入力された文字列をMainActivityのTextViewに表示します。

実行結果

プロジェクトを実行します。下図の画面が表示されます。[Button]をタップします。


[Button]をタップすると下図のダイアログボックスの画面が表示されます。


ダイアログボックス内のテキストボックスに文字を入力し、OKばタンを押します。


ダイアログボックスが閉じダイアログボックス内のテキストボックスに入力した文字列が、MainActivityに配置したTextViewに表示されます。

WebViewの配置 (補足)

WebViewを表示させることもできます。

コード

package com.iPentec.customdialog;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.LayoutInflater;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.EditText;
import android.widget.TextView;
import android.webkit.WebView;

public class MainActivity extends Activity {
  private View inputView;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  public void button1_click(View view){
    //showDialog(CustomViewCallback)
    LayoutInflater factory = LayoutInflater.from(this);
    inputView = factory.inflate(R.layout.dialog, null);

    WebView webView1 = (WebView)inputView.findViewById(R.id.webView1);
    webView1.loadUrl("http://www.ipentec.com/document/document.aspx?page=index");

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setIcon(android.R.drawable.ic_dialog_alert);
    builder.setTitle("カスタムダイアログ");
    builder.setView(inputView);
    
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int whichButton) {
      }
    });
    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      }
    });
    AlertDialog dialog = builder.create();
    dialog.show();
  }
}

実行結果

ダイアログ内にWebViewが表示され、Webサイトのページを表示しています。

著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-04
作成日: 2013-05-21
iPentec all rights reserverd.