【Kotlin/Android Studio】DatePicker/TimePickerDialogの実装方法!

この記事からわかること
- Android Studio/KotlinでDatePicker/TimePickerDialogの実装方法
- Widgetsでビューに配置する
- スピナーモードの変更方法
- スピナーモードのカレンダーをを非表示にするには?
- 選択された日時データをMainActivityに反映させるには?
- setOnDateChangedListenerとsetOnTimeChangedListenerの使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
DatePickerDialogの実装方法
kotlinでButtonをタップした際に日付を入力できるDatePickerDialogを実装していきます。まずはDatePickerDialogFragment
クラスを用意します。ダイアログとして表示させたいのでDialogFragment
を継承して実装していきます。
DatePickerDialog.OnDateSetListener
DatePickerDialog.OnDateSetListener
を継承することでDatePickerから日付を選択された時に呼び出されるコールバックメソッド(onDateSet)をオーバーライドできます。
onCreateDialogメソッド内
ダイアログを生成するonCreateDialog
メソッド内ではCalendar
クラスを使用して現在の日時情報を取得しています。
おすすめ記事:【Kotlin/Android Studio】現在の日付を取得する方法!DateTimeFormatterの使い方
これでDatePickerDialogの準備ができたのであとはButtonのクリックイベントに合わせて表示させるだけです。

TimePickerDialogの実装方法
同じ要領でTimePickerDialog
も実装していきます。DatePickerDialog
とほぼ同じなので説明は基本的には割愛します。
TimePickerDialog(activity, this, hour, minute,false)
ここでTimePickerDialogを生成していますが、最後の引数はis24HourView
というパラメータで時間を24時間表示にするか12時間表示にするかのフラグです。
これでTimePickerDialogの準備ができたのであとはButtonのクリックイベントに合わせて表示させるだけです。

選択された日時データをMainActivityのビューに反映させる
では実際に選択された日時情報をMainActivity側のビューに反映させてみたいと思います。まずはMainActivity側に「日時情報を受け取りTextViewに反映させるメソッド」を追加します。
続いてDatePickerFragmentクラスの日付が選択された時に呼ばれるonDateSet
メソッド内からMainActivity.ktのupdateDate
メソッドを呼び出します。(依存性とかは無視してます)
これで選択した際に日付情報が反映されるようになりました。

interfaceで依存性を軽減する
おすすめ記事:【Kotlin/Android Studio】FragmentのイベントをActivityで受け取る方法
先ほどの例だとDatePickerFragment
クラスがMainActivity
クラスの参照を持ってしまうのでinterface
を利用して依存性を解消していきたいと思います。まずはDatePickerFragment
クラス内にListener
インターフェースを実装しMainActivityに渡したいデータを引数で受け取るメソッドを用意します。さらにonAttach
メソッドをオーバーライドしてその中からcontext
をListenerへキャストします。
オーバーライドしているonDateSet
メソッド内は上記のように修正します。MainActivity
クラス側ではDatePickerFragment.Listener
を継承させ、先ほどのupdateDate
メソッドを削除しonDataset
メソッドに入れ替えます。
これでMainActivityの参照を持つことなくデータを受け渡すことができました。
Widgetsとして実装する
わざわざダイアログとして実装しなくてもWidgetsとしてビューに配置することも可能です。これによりPickerを自由な位置に配置したり、他のWidgetsと組み合わせたカスタムフラグメントとして実装することができるようになります。
DatePicker

TimePicker

TimePicker
を24時間表示にしたい場合はレイアウトファイルからは指定できずコード側でsetIs24HourView
メソッドにtrue
を渡す必要があります。
スピナーモード
日付や時間を選択するモードとしてスピナーモードがあります。これを実装するにはdatePickerMode
ortimePickerMode
属性にspinner
を渡すだけです。

スピナーモードのカレンダーを非表示にする
しかしDatePicker
ではスピナーモードにしてもカレンダーが表示されたままになってしまいます。これを非表示にするにはandroid:calendarViewShown="false"
属性を付与します。

またその他にも背景色の変更や日付選択の範囲など色々カスタマイズできるので詳細は公式サイトを参考にしてください。
DatePickerDialogでスピナーモードにする
DatePickerDialog
側でスピナーモードにしたい場合はDatePickerDialog
の第二引数にandroid.R.style.Theme_Holo_Dialog
を渡すことで実装できました。
参考文献:Teratail:Kotlin Android 日付や時刻選択をスピナー型で
Widgetsで定義したPickerの変更通知を受け取る
ではPickerを保持するカスタムフラグメントを実装する流れを見ていきます。
- カスタムフラグメント用レイアウトの作成
- カスタムフラグメント用クラスの作成
- イベントリスナーを設定
- アクティビティ側から変更通知とデータを受け取り反映
細かいフラグメントの実装方法については以下の記事を参考にしてください。
1.カスタムフラグメント用レイアウトの作成
まずは実際に表示させるFragmentレイアウトを作成していきます。ここでは特別なことはしてませんので割愛します。
2.カスタムフラグメント用クラスの作成
続いて今回の肝となるFragmentを管理するクラスを仕上げていきます。Listener
を利用したMainActivityへのデータの受け渡しはこちらと一緒です。
3.イベントリスナーを設定
ここで重要なのは以下の部分です。それぞれのWidgetsから呼び出しているsetOnXXXXChangedListener
がデータの変更を検知して呼び出されるコールバックメソッドです。この中に変更時に処理させたいことを実装します。
4.アクティビティ側から変更通知とデータを受け取り反映
ここも特に変わったことはしてません。
これで独自で実装したPickerの値の変化を検知してアクティビティに反映させることができるようになりました。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。