Ashwin
Ashwin

Reputation: 13547

How to prevent dismiss of Time Picker Dialog after time selection?

I am using android's TimePickerDialog this way

val tpd = TimePickerDialog(this, { dialog, h, min -> 
 // I want to dismiss the dialog only if the validations succeed
}, 12, 15, false)
tpd.show()

How do I prevent it from getting auto dismissed after user selects a time? I want to run my validations before I can dismiss the time picker dialog.

Upvotes: 0

Views: 228

Answers (2)

Akaki Kapanadze
Akaki Kapanadze

Reputation: 2672

abstract class TimePickerDialog2(
    context: Context,
    hourOfDay: Int, minute: Int, is24Hour: Boolean
) {
    private val impl = DialogImpl(context, { view, hourOfDay, minute ->
        if (onTimeSet(view, hourOfDay, minute)) {
            dismiss()
        }
    }, hourOfDay, minute, is24Hour)

    fun show() { impl.show() }
    fun dismiss() { impl.dismiss() }

    /** Called when user presses OK button. Return [true] to close dialog, [false] otherwise. */
    abstract fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int)
            : Boolean

    private class DialogImpl(
        context: Context,
        listener: OnTimeSetListener,
        hourOfDay: Int, minute: Int, is24Hour: Boolean
    ) : TimePickerDialog(context, listener, hourOfDay, minute, is24Hour) {

        var skipDismiss = false
        override fun dismiss() { if (skipDismiss) { skipDismiss = false } else { super.dismiss() } }
        override fun onClick(dialog: DialogInterface, which: Int) {
            super.onClick(dialog, which)
            skipDismiss = (which == BUTTON_POSITIVE)
        }
    }
}

Usage

object : TimePickerDialog2(this, 12, 15, false) {
    override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int): Boolean {
        if (/* the validations succeed */) {
            return true
        }
        return false
    }
}.show()

This implementation uses some hacky tricks to work around. Better to use custom AlertDialog solution for this, as @ADM suggested above.

Upvotes: 0

SpiritCrusher
SpiritCrusher

Reputation: 21053

Since TimePickerDialog extends AlertDialog you can get the positive Button and modify its click listener This way.

But the problem here is you will not access to the TimePicker widget because you need it to get the time for validation. Becasue if you override the positive button click your listener will not get called and mTimePicker field is private in TimePickerDialog . Sure you can access it by reflection but that's not right way to do stuff .

As a solution create a Custom AlertDialog . that way you can have control over selection.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TimePicker
    android:id="@+id/TimePicker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
</LinearLayout>


 val alert = AlertDialog.Builder(this)
        alert.setView(R.layout.time_picker)
        alert.setPositiveButton("OK"
        ) { dialog, which -> {
                // validate here
        } }

        alert.setNegativeButton("Cancel"
        ) { dialog, which -> {
            dialog.dismiss()
        } }
        alert.show()

Use This Approach to prevent AlertDialog from getting closed and you are good to go.

Upvotes: 1

Related Questions