【Android】ダイアログ表示 ~ 基本編 / 日付・時間ダイアログ ~

■ はじめに

https://dk521123.hatenablog.com/entry/2013/10/14/002656
https://dk521123.hatenablog.com/entry/2013/10/05/214058
https://dk521123.hatenablog.com/entry/2013/10/06/122942
https://dk521123.hatenablog.com/entry/2013/10/07/005850

の続き。

今回は、日付・時間を入力するためのダイアログを作成してみる。

 とりあえず、どちらかを実装すれば、
ほぼ同じ仕組みなので、流れで作れる。

■ サンプル

* Fragment を日付・時間用、それぞれ追加する
 => 追加するファイルは、普通のクラスとして追加する
 => 今回は「DatePickerFragment.kt」「TimePickerFragment.kt」

日付・時間ダイアログ

DatePickerFragment.kt

import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.widget.DatePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {
    // コールバック関数
    interface OnSelectedListener {
        fun selectedDate(year: Int, month: Int, dayOfMonth: Int)
    }

    private lateinit var listener: OnSelectedListener

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnSelectedListener) {
            listener = context
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = Date().time
        val context = context
        return when {
            context != null -> {
                DatePickerDialog(
                    context,
                    this,
                    calendar.get(Calendar.YEAR),
                    calendar.get(Calendar.MONTH),
                    calendar.get(Calendar.DATE))
            }
            else -> super.onCreateDialog(savedInstanceState)
        }
    }

    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        // データを渡す
        this.listener.selectedDate(year, month, dayOfMonth)
    }
}

TimePickerFragment.kt

import android.app.Dialog
import android.app.TimePickerDialog
import android.content.Context
import android.os.Bundle
import android.widget.TimePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {
    interface OnSelectedListener {
        fun selectedTime(hourOfDay: Int, minute: Int)
    }

    private lateinit var listener: OnSelectedListener

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is TimePickerFragment.OnSelectedListener) {
            listener = context
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = Date().time
        val context = context
        return when {
            context != null -> {
                TimePickerDialog(
                    context,
                    this,
                    calendar.get(Calendar.HOUR_OF_DAY),
                    calendar.get(Calendar.MINUTE),
                true)
            }
            else -> super.onCreateDialog(savedInstanceState)
        }
    }

    override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
        this.listener.selectedTime(hourOfDay, minute)
    }
}

呼び出し側

MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.dk.jpalarm.dialogs.DatePickerFragment
import com.dk.jpalarm.dialogs.TimePickerFragment
import kotlinx.android.synthetic.main.activity_set_alarm.*

class MainActivity :
    AppCompatActivity(),
    DatePickerFragment.OnSelectedListener,
    TimePickerFragment.OnSelectedListener{
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_set_alarm)

        dateEditText.setOnClickListener {
            val dialog = DatePickerFragment()
            dialog.show(supportFragmentManager, "date_picker")
        }
        timeEditText.setOnClickListener {
            val dialog = TimePickerFragment()
            dialog.show(supportFragmentManager, "time_picker")
        }
    }

    override fun selectedDate(year: Int, month: Int, dayOfMonth: Int) {
        dateEditText.setText("%04d/%02d/%02d".format(year, month + 1, dayOfMonth))
    }

    override fun selectedTime(hourOfDay: Int, minute: Int) {
        timeEditText.setText("%02d:%02d".format(hourOfDay, minute))
    }
}

参考文献

https://qiita.com/fumiyakawauso/items/dbb0517144f2a4400e6a

関連記事

ダイアログ表示 ~ 入門編 / トースト・Toast ~
https://dk521123.hatenablog.com/entry/2013/10/14/002656
ダイアログ表示 ~ 基本編 / アラートダイアログ ~
https://dk521123.hatenablog.com/entry/2013/10/05/214058
ダイアログ表示 ~ 基本編 / YES/NO/CANCELボタン ~
https://dk521123.hatenablog.com/entry/2013/10/06/122942
ダイアログ表示 ~ 基本編 / リスト選択 ~
https://dk521123.hatenablog.com/entry/2013/10/07/005850
ダイアログ表示 ~ 基本編 / チェックボックスラジオボタン
https://dk521123.hatenablog.com/entry/2013/10/09/001500
ダイアログ表示 ~ 基本編 / EditText付きダイアログ ~
https://dk521123.hatenablog.com/entry/2020/10/03/000000
ダイアログ表示 ~ 基本編 / Notification(通知) ~
https://dk521123.hatenablog.com/entry/2020/08/01/000000
Kotlin / Realm で英単語帳を作る
https://dk521123.hatenablog.com/entry/2020/07/20/232009
アラーム機能を実装するには
https://dk521123.hatenablog.com/entry/2020/07/14/000000