選択ツール

Android には、ユーザーが時刻または日付を選択するためのコントロールが、すぐに使えるダイアログとして用意されています。各選択ツールは、時刻の要素(時、分、午前 / 午後)または日付の要素(月、日、年)を選択するコントロールを提供します。これらの選択ツールを使用すると、有効かつ正しい形式で、ユーザーの言語 / 地域に合わせた時刻または日付を選択できます。

DialogFragment を使用して、時刻または日付の各選択ツールをホストすることをおすすめします。DialogFragment は、ダイアログのライフサイクルを管理し、さまざまなレイアウト構成(ハンドセットの基本ダイアログのレイアウトや、大画面のレイアウトの埋め込み領域など)で選択ツールを表示できるようにします。

DialogFragment は、当初 Android 3.0(API レベル 11)のプラットフォームに追加されましたが、アプリが 3.0 より古いバージョンの Android をサポートしている場合でも(Android 1.6 でさえも)、下位互換性の維持のためにサポート ライブラリで利用できる DialogFragment クラスを使用することが可能です。

注: 下記のコードサンプルは、DialogFragmentサポート ライブラリ API を使用して、時刻と日付を選択するツールのダイアログを作成する方法を示しています。アプリの minSdkVersion が 11 以上の場合は、代わりに DialogFragment のプラットフォーム バージョンを使用できます。

キーとなるクラスは次のとおりです。

フラグメントの概要もご覧ください。

時刻選択ツールの作成

DialogFragment を使用して TimePickerDialog を表示するには、DialogFragment を拡張してフラグメントの onCreateDialog() メソッドから TimePickerDialog を返すフラグメント クラスを定義する必要があります。

注: アプリが 3.0 より古いバージョンの Android に対応している場合は、ライブラリを使用するためのプロジェクトのセットアップに記載されているとおり、サポート ライブラリを使用する Android プロジェクトをセットアップしていることを確認してください。

時刻選択ツール用の DialogFragment の拡張

TimePickerDialog 用の DialogFragment を定義するには、以下を行う必要があります。

次の例をご覧ください。

Kotlin

class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current time as the default values for the picker
        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY)
        val minute = c.get(Calendar.MINUTE)

        // Create a new instance of TimePickerDialog and return it
        return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) {
        // Do something with the time chosen by the user
    }
}

Java

public static class TimePickerFragment extends DialogFragment
                            implements TimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current time as the default values for the picker
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        // Create a new instance of TimePickerDialog and return it
        return new TimePickerDialog(getActivity(), this, hour, minute,
                DateFormat.is24HourFormat(getActivity()));
    }

    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        // Do something with the time chosen by the user
    }
}

コンストラクタの引数については、TimePickerDialog クラスをご覧ください。

ここで必要なのは、このフラグメントのインスタンスをアクティビティに追加するイベントだけです。

時刻選択ツールの表示

上記のような DialogFragment を定義したら、DialogFragment のインスタンスを作成して show() を呼び出すことにより、時刻選択ツールを表示できます。

たとえば、次のボタンは、クリックするとダイアログを表示するメソッドを呼び出します。

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_time"
    android:onClick="showTimePickerDialog" />

ユーザーがこのボタンをクリックすると、システムは次のメソッドを呼び出します。

Kotlin

fun showTimePickerDialog(v: View) {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Java

public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(getSupportFragmentManager(), "timePicker");
}

このメソッドは、上記で定義された DialogFragment の新しいインスタンスで show() を呼び出します。show() メソッドには、FragmentManager のインスタンスとフラグメントの一意のタグ名が必要です。

注意: アプリが Android 3.0 より前のバージョンに対応している場合は、getSupportFragmentManager() を呼び出して FragmentManager のインスタンスを取得してください。また、時刻選択ツールを表示するアクティビティで、標準の Activity クラスではなく FragmentActivity を拡張していることも確認してください。

日付選択ツールの作成

DatePickerDialog の作成は、TimePickerDialog の作成と同じです。唯一の違いは、フラグメントに対して作成するダイアログです。

DialogFragment を使用して DatePickerDialog を表示するには、DialogFragment を拡張してフラグメントの onCreateDialog() メソッドから DatePickerDialog を返すフラグメント クラスを定義する必要があります。

日付選択ツール用の DialogFragment の拡張

DatePickerDialog 用の DialogFragment を定義するには、以下を行う必要があります。

次の例をご覧ください。

Kotlin

class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current date as the default date in the picker
        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val day = c.get(Calendar.DAY_OF_MONTH)

        // Create a new instance of DatePickerDialog and return it
        return DatePickerDialog(activity, this, year, month, day)
    }

    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        // Do something with the date chosen by the user
    }
}

Java

public static class DatePickerFragment extends DialogFragment
                            implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // Do something with the date chosen by the user
    }
}

コンストラクタの引数については、DatePickerDialog クラスをご覧ください。

ここで必要なのは、このフラグメントのインスタンスをアクティビティに追加するイベントだけです。

日付選択ツールの表示

上記のような DialogFragment を定義したら、DialogFragment のインスタンスを作成して show() を呼び出すことにより、日付選択ツールを表示できます。

たとえば、次のボタンは、クリックするとダイアログを表示するメソッドを呼び出します。

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_date"
    android:onClick="showDatePickerDialog" />

ユーザーがこのボタンをクリックすると、システムは次のメソッドを呼び出します。

Kotlin

fun showDatePickerDialog(v: View) {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Java

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getSupportFragmentManager(), "datePicker");
}

このメソッドは、上記で定義された DialogFragment の新しいインスタンスで show() を呼び出します。show() メソッドには、FragmentManager のインスタンスとフラグメントの一意のタグ名が必要です。

自動入力機能付き選択ツールの使用

Android 8.0 で自動入力フレームワークが導入され、ユーザーはデータを保存して後で別のアプリのフォームへの入力に使用できるようになりました。選択ツールを利用すると、日付データまたは時刻データを格納するフィールドの値をユーザーが変更できる UI を提供できます。そのため、自動入力を利用する場合、選択ツールは非常に有用です。たとえば、クレジット カードフォームの場合、日付選択ツールを用意すると、ユーザーは簡単にクレジット カードの有効期限を入力または変更できます。

選択ツールはダイアログであるため、他のフィールドと一緒にアクティビティに表示されることはありません。選択ツールが表示されていないときに選択ツールデータを表示するには、EditText などの別のビューを使用します。そうすれば、選択ツールが表示されていないときに値を表示できます。

EditText オブジェクトは、ネイティブで AUTOFILL_TYPE_TEXT 型の自動入力データを想定します。対照的に、自動入力サービスは、適切なデータ表現を作成できるように、データを AUTOFILL_TYPE_DATE として保存する必要があります。型の不整合を解決するには、EditText から継承するカスタムビューを作成し、AUTOFILL_TYPE_DATE 型の値を正しく処理するために必要なメソッドを実装することをおすすめします。

AUTOFILL_TYPE_DATE 型の値を処理できる EditText のサブクラスを作成するには、次の手順を実施する必要があります。

  1. EditText から継承するクラスを作成します。
  2. AUTOFILL_TYPE_DATE を返す getAutofillType() メソッドを実装します。
  3. ミリ秒単位の日付を表す AutofillValue オブジェクトを返す getAutofillValue() メソッドを実装します。戻り値オブジェクトを作成するには、forDate() メソッドを使用して AutofillValue オブジェクトを生成します。
  4. autofill() メソッドを実装します。このメソッドは、AUTOFILL_TYPE_DATE 型の AutofillValue パラメータを処理するロジックを提供します。パラメータを処理するには、パラメータの適切な文字列表現(mm/yyyy など)を作成します。文字列表現を使用して、ビューの text プロパティを設定します。
  5. ユーザーが EditText のカスタム サブクラスで日付を編集するときに選択ツールを表示する機能を実装します。ビューでは、ユーザーが選択ツールで選択した値の文字列表現で text プロパティを更新する必要があります。

AUTOFILL_TYPE_DATE 値を処理する EditText のサブクラスの例については、自動入力フレームワーク サンプル(Java | Kotlin)をご覧ください。

カスタムビューの自動入力サポートの詳細については、カスタムビューのサポートをご覧ください。