アプリに選択ツールを追加する

Android には、すぐに使用できるダイアログとして、時刻または日付をユーザーが選択できるコントロールが用意されています。これらの選択ツールでは、時間(時間、分、AM/PM)または日付(月、日、年)の各部分を選択するためのコントロールを提供します。

material.io の時刻選択ツールの例
図 1.モバイル カレンダーの選択ツールでの時間の選択。

これらの選択ツールを使用すると、有効かつ正しい形式で、ユーザーの言語 / 地域に合わせた時刻または日付を選択できます。

material.io のモーダル日付選択ツールの例
図 2. モーダル日付選択ツール。

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

時刻選択ツールを作成する

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

時間選択ツール用に DialogFragment を拡張する

TimePickerDialogDialogFragment を定義する手順は次のとおりです。

  • TimePickerDialog のインスタンスを返すように onCreateDialog() メソッドを定義します。
  • ユーザーが時刻を設定したときにコールバックを受け取る TimePickerDialog.OnTimeSetListener インターフェースを実装します。

次の例をご覧ください。

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 the user picks.
    }
}

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 the user picks.
    }
}

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

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

時間選択ツールを表示

上記の例のように DialogFragment を定義した後、DialogFragment のインスタンスを作成して show() メソッドを呼び出すと、時間選択ツールを表示できます。

たとえば、タップされたときにダイアログを表示するメソッドを呼び出すボタンを次に示します。

<Button
    android:id="@+id/pickTime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick time" />

ユーザーがこのボタンをタップすると、次のメソッドが呼び出されます。

Kotlin

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Java

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker");
}

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

日付選択ツールを作成する

DatePickerDialog を作成することは、TimePickerDialog を作成することに似ています。違いはフラグメント用に作成するダイアログです。

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

日付選択ツール用に DialogFragment を拡張する

DatePickerDialogDialogFragment を定義する手順は次のとおりです。

  • DatePickerDialog のインスタンスを返すように onCreateDialog() メソッドを定義します。
  • ユーザーが日付を設定したときにコールバックを受け取る DatePickerDialog.OnDateSetListener インターフェースを実装します。

次の例をご覧ください。

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(requireContext(), this, year, month, day)

    }

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

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(requireContext(), this, year, month, day);
    }

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

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

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

日付選択ツールを表示

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

たとえば、タップされたときにダイアログを表示するメソッドを呼び出すボタンを次に示します。

<Button
    android:id="@+id/pickDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick date"/>

ユーザーがこのボタンをタップすると、次のメソッドが呼び出されます。

Kotlin

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Java

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment();
    newFragment.show(supportFragmentManager, "datePicker");
}

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

自動入力内で選択ツールを使用する

Android は 2017 年に、さまざまなアプリのフォームへの入力に使用できるデータを保存できる自動入力フレームワークを導入しました。自動入力のシナリオで選択ツールを使用すると、日付データや時刻データを格納するフィールドの値をユーザーが変更できる 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. getAutofillValue() メソッドを実装します。このメソッドは、ミリ秒単位で日付を表す AutofillValue オブジェクトを返します。戻りオブジェクトを作成するには、forDate() メソッドを使用して AutofillValue オブジェクトを生成します。
  4. autofill() メソッドを実装します。このメソッドは、AUTOFILL_TYPE_DATE 型の AutofillValue パラメータを処理するロジックを提供します。パラメータを処理するには、パラメータの適切な文字列表現(mm/yyyy など)を作成します。文字列表現を使用して、ビューの text プロパティを設定します。
  5. ユーザーが EditText のカスタム サブクラスで日付を編集するときに選択ツールを表示する機能を実装します。このビューは、ユーザーが選択ツールで選択した値の文字列表現で text プロパティを更新します。

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

カスタムビューの自動入力サポートを証明する方法について詳しくは、自動入力フレームワークをご覧ください。