marunomaruno-memo

marunomaruno-memo

Android ダイアログ (5) 日付と時刻の選択ダイアログ その1

2011年08月21日 | Android
ダイアログ (5) 日付の選択ダイアログ
================================================================================

日付と時刻を選択するダイアログ。
それぞれ、DatePickerDialog と TimePickerDialog を使う。
また、日時を同時に指定するには、自分で、日付と時刻を選択するダイアログを作る必要
がある。これは、カスタムダイアログとして、AlertDialog を使う。このとき、カスタム
ビューとしては、日付と時刻を選択するための DatePicker と TimePicker を組み合わせ
て使う。

それぞれのサンプルは以下のとおり。

Dialog07  日付の選択ダイアログ
Dialog071 日付の選択ダイアログで、タイトルの形式をカスタマイズ
Dialog08  時刻の選択ダイアログ ※
Dialog09  日付と時刻の選択ダイアログが連続して設定 ※
Dialog091 日時の選択ダイアログ(カスタムダイアログ) ※

※(6)で紹介

■ 日付の選択ダイアログ

日付を選択するダイアログは、DatePickerDialog を使う。
とくに何もしなくても、タイトルや設定ボタン、キャンセル・ボタンなどは、日本語で表
示してくれる。
ただ、タイトルの形式は、次の形式で表示される。
    土曜日, 8月 20, 2011
この形式の変更は、次のサンプル Dialog071 で補足する。


□ Dialog07Activity.java
---
package jp.marunomaruno.android.sample;

import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.TextView;

public class Dialog07Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

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

        Calendar calendar = Calendar.getInstance();                       // (1)
        int year = calendar.get(Calendar.YEAR);
        int monthOfYear = calendar.get(Calendar.MONTH);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog dialog = new DatePickerDialog(this,
                new DateSetHandler(date), year, monthOfYear, dayOfMonth); // (2)
//        dialog.setTitle(String.format(getString(R.string.date_format), calendar)); // (3)
        dialog.show();
    }

    private class DateSetHandler implements DatePickerDialog.OnDateSetListener { // (4)
        private TextView date;

        public DateSetHandler(TextView date) {
            this.date = date;
        }

        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                int dayOfMonth) {                                         // (5)
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthOfYear, dayOfMonth);

            date.setText(String.format(getString(R.string.date_format), calenda
r)); // (6)
        }
    }
}
---

□ Calendar calendar = Calendar.getInstance();                            // (1)

ダイアログには、デフォルトで今日の日付を表示するので、Calendar.getInstance() で、
カレンダー日付のオブジェクトを設定する。


□ DatePickerDialog dialog = new DatePickerDialog(this,
             new DateSetHandler(date), year, monthOfYear, dayOfMonth);    // (2)

DatePickerDialog オブジェクトを生成する。
このとき、日付が設定されたときのリスナー、最初に表示される年・月・日を指定する。

・クラス階層
java.lang.Object
   + android.app.Dialog
         + android.app.AlertDialog
               + android.app.DatePickerDialog

・コンストラクター
---
DatePickerDialog(Context context, DatePickerDialog.OnDateSetListener callBack, 
                    int year, int monthOfYear, int dayOfMonth)
DatePickerDialog(Context context, int theme, 
                    DatePickerDialog.OnDateSetListener callBack, 
                    int year, int monthOfYear, int dayOfMonth)
---


□ // dialog.setTitle(String.format(getString(R.string.date_format), calendar));
 // (3)

コメントアウトされているが、setTitle() を使うことで、タイトルを設定する。ただし、
日付が変わったら、ここで指定した文字列は壊れ、デフォルトのタイトルの形式になる。
デフォルトのタイトルは、次の形式で表示される。
    土曜日, 8月 20, 2011
これの形式を変更するのは、次に示すサンプル Dialog071 で示す。


□ private class DateSetHandler implements DatePickerDialog.OnDateSetListener {  // (4)
□ public void onDateSet(DatePicker view, int year, int monthOfYear, 
                            int dayOfMonth) {                             // (5)

ダイアログで日付を設定したときに呼び出されるリスナー DatePickerDialog.OnDateSetL
istener を実装するクラスの定義。

DatePickerDialog.OnDateSetListener

日付を設定し終えて、設定ボタンをクリックしたときに呼ばれるリスナー・インターフ
ェース。
つぎのメソッドを実装する。
abstract void  onDateSet(DatePicker view, int year, int monthOfYear, 
                            int dayOfMonth)

最終的に確定した日付が引数で受け取れる。ただし、monthOfYear は、Calendar クラス
と同じで、0~11 の値でくる。

今回は、受け取ったテキストビューに、この日付を組み立てて設定している。

※
---
このメソッドでは、引数 view から、設定されている日付を取得できるので、引数の 
year, monthOfYear, dayOfMonth はいらないと思うが、どうなんだろう。
単に使いやすさのためかな。
---


□ date.setText(String.format(getString(R.string.date_format), calendar));// (6)

最終的な日付をテキストビューに設定している。
形式は、リソース values/strings.xml で定義している。
内容は、以下のとおり。
    <string name="date_format">%tF</string>

これは、ISO 8601 format 形式で、以下の書式になる。
    yyyy-mm-dd


□ layout/main.xml
---

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/date"
    />
</LinearLayout>
---

□ values/strings.xml
---

<resources>
    <string name="hello">Hello World, Dialog07Activity!</string>
    <string name="app_name">Dialog07</string>
    <string name="date_format">%tF</string>
</resources>
---


■タイトルの形式をカスタマイズする

先のサンプル Dialog07 では、ダイアログのタイトルを表示する前に設定しても、日付を
変えると、タイトルの形式も変わってしまった。
タイトルの形式を変えないようにするには、DatePickerDialog を直接使うのではなく、
DatePicker をビューとしたカスタマイズのダイアログ(AlertDialog)として定義して使
う。

□ Dialog071Activity.java
---
package jp.marunomaruno.android.sample;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.widget.DatePicker;
import android.widget.TextView;

public class Dialog071Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

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

        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int monthOfYear = calendar.get(Calendar.MONTH);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);

        DatePicker picker = new DatePicker(this);                       // (1)

        AlertDialog dialog = new AlertDialog.Builder(this)              // (2)
                .setView(picker)                                        // (3)
                .setTitle(String.format(getString(R.string.date_format),
                                        calendar))                      // (4)
                .setPositiveButton(R.string.set_title, new DateSetHandler(picker,
                        date))                                          // (5)
                .setNegativeButton(R.string.cancel_title, null)         // (6)
                .show();
        picker.init(year, monthOfYear, dayOfMonth, new DateChangedHandler(dialog)); // (7)
        Log.d("TEST", String.format("AlertDialog: %s", dialog.toString()));
    }

    private class DateChangedHandler implements DatePicker.OnDateChangedListener { // (8)
        private AlertDialog dialog;

        public DateChangedHandler(AlertDialog dialog) {
            this.dialog = dialog;
        }

        @Override
        public void onDateChanged(DatePicker view, int year, int monthOfYear,
                int dayOfMonth) {                                       // (9)
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthOfYear, dayOfMonth);

            Log.d("TEST", String.format("d: %tc", calendar));

            dialog.setTitle(String.format(getString(R.string.date_format),
                    calendar));                                         // (10)
        }
    }

    private class DateSetHandler implements DialogInterface.OnClickListener { // (11)
        private DatePicker picker;
        private TextView date;

        public DateSetHandler(DatePicker picker, TextView date) {
            this.picker = picker;
            this.date = date;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {        // (12)
            Calendar calendar = Calendar.getInstance();
            calendar.set(picker.getYear(), picker.getMonth(), 
                    picker.getDayOfMonth());                            // (13)

            Log.d("TEST", String.format("c: %tc", calendar));

            date.setText(String.format(getString(R.string.date_format),
                    calendar));
        }
    }
}
---

□ DatePicker picker = new DatePicker(this);                        // (1)

日付を選択するためのビューとして、DatePicker クラスを用いる。

・クラス階層
java.lang.Object
   + android.view.View
         + android.view.ViewGroup
               + android.widget.FrameLayout
                     + android.widget.DatePicker

・コンストラクター
---
DatePicker(Context context)
DatePicker(Context context, AttributeSet attrs)
DatePicker(Context context, AttributeSet attrs, int defStyle)
---

自分自身の画面で使用するので、context は、自分自身(this)を用いる。

・主なメソッド
---
void  init(int year, int monthOfYear, int dayOfMonth, 
                DatePicker.OnDateChangedListener onDateChangedListener)
---


□ AlertDialog dialog = new AlertDialog.Builder(this)                // (2)

DatePicker オブジェクトを乗せるための AlertDialog オブジェクトを生成する。


□ .setView(picker)                                                 // (3)

カスタムビューとして、DatePicker オブジェクトを設定する。


□ .setTitle(String.format(getString(R.string.date_format),calendar))  // (4)

ダイアログのタイトルを ISO 形式で設定する。リソースファイルで定義されているのは、
以下の形式である。
    %tF


□ .setPositiveButton(R.string.set_title, new DateSetHandler(picker, date)) // (5)

「設定ボタン」を設置する。ここでは、DialogInterface.OnClickListener を実装してい
るオブジェクトをリスナーとして、ダイアログで設定した日付を表示するためのテキスト
ビューを引数として渡している。


□ .setNegativeButton(R.string.cancel_title, null)                  // (6)

「キャンセル・ボタン」を設定する。
リスナー・オブジェクトは null になっているので、ボタンを押されたときは何もしない。


□ picker.init(year, monthOfYear, dayOfMonth, new DateChangedHandler(dialog)); // (7)

DatePicker オブジェクトを初期化する。
引数は、最初に出したい日付(年・月・日)、日付が変化したときに動作するリスナーのオ
ブジェクト。
今回は、日付が変わったときに、ダイアログのタイトルも変更したいので、リスナーには、
ダイアログのオブジェクトを渡している。


□ private class DateChangedHandler implements DatePicker.OnDateChangedListener { // (8)

引数は、最初に出したい日付(年・月・日)、日付が変化したときに動作するリスナーを定
義。このオブジェクトは、DatePicker.OnDateChangedListener インターフェースを実装
する。

DatePicker.OnDateChangedListener

日付の選択で、日付が変わったことに対するバンドラーを定義するリスナー・インターフ
ェース。

・メソッド
---
abstract void  onDateChanged(DatePicker view, int year, int monthOfYear, 
                                int dayOfMonth)
---

設定ボタンが押されたときは、これは動作しない。したがって、まったく日付を変える必
要がない場合は、設定ボタンのリスナーで、日付を設定する必要がある。


□ public void onDateChanged(DatePicker view, int year, int monthOfYear, 
                                int dayOfMonth) {            // (9)

ダイアログで日付が変わったことに対するハンドラー・メソッド。


□ dialog.setTitle(String.format(getString(R.string.date_format), calendar)); // (10)

ダイアログで日付が変わったら、その日付をタイトルに設定している。
タイトルの形式は、ISO 形式として、リソースに設定している。


□ private class DateSetHandler implements DialogInterface.OnClickListener { // (11)
□ public void onClick(DialogInterface dialog, int which) {  // (12)

設定ボタンがクリックされたことに対するリスナーのクラスとハンドラー・メソッドを定
義する。(「ダイアログ (1)」を参照)


□ calendar.set(picker.getYear(), picker.getMonth(), picker.getDayOfMonth()); // (13)

DatePicker オブジェクトを受け取っているので、そこから日付を取得して設定する。


□ values/strings.xml
---

<resources>
    <string name="hello">Hello World, Dialog071Activity!</string>
    <string name="app_name">Dialog071</string>
    <string name="set_title">設定</string>
    <string name="cancel_title">キャンセル</string>
    <string name="date_format">%tF</string>
</resources>
---
                                                                        以上


最新の画像もっと見る

コメントを投稿