妄想プログラマのらくがき帳 : 3月 2013

2013年3月25日月曜日

[Android]ダイアログを表示する。その2。

「いろんな種類のダイアログの表示方法についてまとめてみました。」のその2です。

・リスト選択のダイアログ

リスト項目から1つを選択するタイプのダイアログです。

// リスト項目を定義
final String[] listItems = new String[] { "small", "medium", "large" };

AlertDialog.Builder builder = new AlertDialog.Builder(this); // ※thisはActivity自身
builder.setTitle("サイズ選択")
        .setItems(listItems, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                System.out.println("selected size => " + listItems[which]);
            }
        });

builder.show();
AlertDialogと同じくAlertDialog.Builderを使います。
AlertDialog.Builder.setItems()でリスト項目を設定することで、リスト選択のダイアログになります。
リストで何が選択されたかは、onClick()の第2引数whichに格納されているindexで分かります
(上のコードの場合、"small"が選択されたらwhichには0が格納されます)。


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

チェックボックスで複数選択するタイプのダイアログです。

// チェック項目を定義
final String[] checkItems = new String[] { "rock", "pop", "metal", "jazz" };

AlertDialog.Builder builder = new AlertDialog.Builder(this); // ※thisはActivity自身
builder.setTitle("ジャンル選択")
        .setMultiChoiceItems(checkItems, null, new OnMultiChoiceClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                // ここでチェック状態を一時保存しておく
                if (isChecked) {
                    System.out.println("checked => " + checkItems[which]);
                }
                else {
                    System.out.println("unchecked => " + checkItems[which]);
                }
            }
        })
        .setPositiveButton("OK", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // ここで一時保存しておいた選択状態を正式保存する。
            }

        })
        .setNegativeButton("Cancel", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // ダイアログでの変更を破棄するため、何もしない。
            }
        });

builder.show();
これもAlertDialog.Builderを使います。
AlertDialog.Builder.setMultiChoiceItems()で項目を設定することで、チェックボックスのダイアログになります。

OnMultiChoiceClickListener.onClick()はチェックボックスのON/OFFが変更されるたびに呼ばれ、
引数whichには変更された項目のindex、引数isCheckedには変更後チェック状態が格納されています。
onClick()内で一時変数に各項目のチェック状態を保存しておき、「肯定ボタン」が押されたときに一時変数を本体や設定に反映するというのが一般的な使い方だと思います。


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

ラジオボタンで単数選択するタイプのダイアログです。

// 選択項目を定義
final String[] radioItems = new String[] { "classic", "modern", "blue", "green", "black", "special" };

AlertDialog.Builder builder = new AlertDialog.Builder(this); // ※thisはActivity自身
builder.setTitle("テーマ選択")
        .setSingleChoiceItems(radioItems, 0, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // ここで選択状態を一時保存しておく
                System.out.println("selected theme => " + radioItems[which]);
            }
        })
        .setPositiveButton("OK", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // ここで一時保存しておいた選択状態を正式保存する。
            }

        })
        .setNegativeButton("Cancel", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // ダイアログでの変更を破棄するため、何もしない。
            }
        });

builder.show();
ほとんどチェックボックスのダイアログと同じですが、AlertDialog.Builder.setSingleChoiceItems()で項目を設定するところが異なります。

2013年3月18日月曜日

[Android]ダイアログを表示する。その1。

いろんな種類のダイアログの表示方法についてまとめてみました。

・AlertDialog

まずは標準的なダイアログであるAlertDialogです。

// タイトル、メッセージ、ボタンを設定
AlertDialog.Builder builder = new AlertDialog.Builder(this); // ※thisはActivity自身
builder.setTitle("Alert Dialog") // タイトル
        .setMessage("message.") // メッセージ
        // 肯定ボタン
        .setPositiveButton("Yes", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                System.out.println("YesButtoon clicked in alert dialog.");
            }

        })
        // 否定ボタン
        .setNegativeButton("No", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                System.out.println("NoButtoon clicked in alert dialog.");
            }
        })
        // 中立ボタン
        .setNeutralButton("Cancel", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                System.out.println("CancelButtoon clicked in alert dialog.");
            }
        });
// ダイアログを表示
builder.show();
AlertDialog.Builderで各設定を行い、AlertDialog.Builder.show()で表示します。
キャプチャ画像を見れば分かりますが、ボタンの並びは左から「否定ボタン」「中立ボタン」「肯定ボタン」になります。
※但し、この並びはAndroidのバージョンで変わる可能性があるので(実際、たしか4.0になった時に否定と肯定の位置が入れ替わってます)、左側ボタンを設定したいからsetNegativeButton()を使うといった実装は止めましょう。


・DatePickerDialog

DatePickerDialogは日付を選択するためのダイアログです。

// 日付が設定されたときのリスナを定義
OnDateSetListener listener = new OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        System.out.println("picked date => " + year + "/" + monthOfYear + "/" + dayOfMonth);
    }
};

// 初期表示日付を今日に設定してダイアログを表示
Calendar now = Calendar.getInstance();
new DatePickerDialog(this, // ※thisはActivity自身
                        listener,
                        now.get(Calendar.YEAR),
                        now.get(Calendar.MONTH),
                        now.get(Calendar.DATE)).show();
onDateSet()はダイアログで「設定ボタン」が押されたときに呼ばれます。
ダイアログで設定された日付が引数に格納されているので、ここで必要に応じて保存処理等を行います。


・TimePickerDialog

TimePickerDialogは時刻を選択するためのダイアログです。

// 時間が設定されたときのリスナを定義
OnTimeSetListener listener = new OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        System.out.println("picked time => " + hourOfDay + " : " + minute);
    }
};

// 初期表示時間を現時刻に設定してダイアログを表示
Calendar now = Calendar.getInstance();
new TimePickerDialog(this, // ※thisはActivity自身
                        listener,
                        now.get(Calendar.HOUR_OF_DAY),
                        now.get(Calendar.MINUTE),
                        true).show();
基本的にDatePickerDialogと同じです。OnTimeSetListener()はダイアログで「設定ボタン」が押されたときに呼ばれるので、ここで保存処理等を行います。
コンストラクタの5番目の引数is24HourViewは、24時間表記かどうかを指定します。trueにすると24時間表記、falseにすると12時間表記になります。

2013年3月11日月曜日

[Android]ブロードキャストインテントを受け取る

Androidには明示的/暗黙的インテントの他にブロードキャストインテントという仕組みがあります。
明示的/暗黙的インテントは特定のアクティビティのみが受信するのに対して、
ブロードキャストインテントは複数の受信者(レシーバ)が受信することができます。

ブロードキャストインテントの一例を挙げます。例えば、
・バッテリー残量が残り少なくなった
・スクリーンがONになった
といったイベントが発生したとき、Androidシステムはブロードキャストインテントを送信します。
複数の受信者はこれらのインテントを受け取ることで、イベント発生を知ることができ、各々の適切な処理を行うことができます。

システムから送信されるブロードキャストインテントには以下のようなものがあります。

ACTION_TIME_TICK現在時刻が変わった(分ごとに送信)。
ACTION_BOOT_COMPLETEDシステムの起動が完了した。
ACTION_BATTERY_CHANGEDバッテリーの状態が変化した。

この他にも多くのブロードキャストインテントが定義されています。
(http://developer.android.com/reference/android/content/Intent.htmlを参照)

また、独自のインテントをブロードキャストすることもできます。
// 独自のインテントをブロードキャスト送信
Intent myBroadcast = new Intent("com.example.broadcastsender.BUTTON_CLICKED");
sendBroadcast(myBroadcast);

ブロードキャストインテントはブロードキャストレシーバに対して送信されるので、
受信するにはブロードキャストレシーバを登録する必要があります。

ブロードキャストレシーバを登録する

登録方法は2通りあります。

1.registerReceiver()で動的に登録する
以下のサンプルコードは、ACTION_TIME_TICKを受信したら現在時刻をTextViewに表示するものです。
ACTION_TIME_TICKのレシーバをonCreate()内で動的に登録しています。
public class MainActivity extends Activity {

    private TextView textView;
    BroadcastReceiver receiver;

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

        textView = (TextView) findViewById(R.id.textView);

        // ACTION_TIME_TICKを受信するレシーバを登録する
        IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // ACTION_TIME_TICKを受信したら、TextViewに時刻を表示する
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd kk:mm:ss");
                textView.setText(dateFormat.format(new Date()));
            }
        };
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onDestroy() {
        // 登録したレシーバを解除する
        unregisterReceiver(receiver);
        super.onDestroy();
    }

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

2. マニフェストファイルで静的に登録する
静的に登録するには、マニフェストファイルでレシーバを登録します。
登録するレシーバはBroadcastReceiverを継承して作成しておきます。
public class BatteryLowReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // BATTERY_LOWを受信したらメッセージを表示
        Toast.makeText(context, "Battery low!", Toast.LENGTH_LONG).show();
    }
}
マニフェストファイルでは、受信するインテントとレシーバを設定します。
        <receiver android:name="com.example.broadcastreceivesample.BatteryLowReceiver">
            <intent-filter ><action android:name="android.intent.action.BATTERY_LOW"/></intent-filter>
        </receiver>