3

If I use the TimePickerDialog in Jelly Bean, the dialog doesn't have a cancel button, and no matter what I do (like try the back button), the onTimeSet will always fire, so I have no way of knowing if the user didn't want to take action or not.

I've tried adding onCancel and onDismiss handlers, but the cancel is called after the onTimeSet handler.

On ICS, GB, there's a cancel button that works just fine.

Create default application, add Button to layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Me" >
    </Button>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />

</RelativeLayout>

And then have the following in the main code:

package com.example.example;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Dialog d = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        Log.i("Hello", "onTimeSet called");
                    }
                }, 8, 0, false);
                d.setCancelable(true);
                d.setOnCancelListener(new TimePickerDialog.OnCancelListener() {

                    @Override
                    public void onCancel(DialogInterface dialog) {
                        Log.i("Hello", "onCancel called");

                    }
                });

                d.setOnDismissListener(new TimePickerDialog.OnDismissListener() {

                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        Log.i("Hello", "onDismiss called"); 
                    }
                });

                d.show();
            }
        });   
    }
}
casperOne
  • 73,706
  • 19
  • 184
  • 253
bryan
  • 798
  • 7
  • 18
  • You need to post your answer *as an answer*. Do *not* edit the question. Then, you can mark your answer as the accepted answer in two days. I've rolled back your edit. You can still get the contents of the previous edit through the [revisions](http://stackoverflow.com/posts/12031663/revisions). – casperOne Aug 20 '12 at 11:50
  • Link to the [related post on DatePickerDialog](http://stackoverflow.com/questions/11444238/jelly-bean-datepickerdialog-is-there-a-way-to-cancel). – Joe Aug 20 '12 at 12:05

4 Answers4

2

Until the bug fixed I suggest not use DatePickerDialog or TimePickerDialog use custom made AlertDialog with TimePicker/DatePicker widget;

Change TimePickerDialog with;

    final TimePicker timePicker = new TimePicker(this);
    timePicker.setIs24HourView(true);
    timePicker.setCurrentHour(20);
    timePicker.setCurrentMinute(15);

    new AlertDialog.Builder(this)
            .setTitle("Test")
            .setPositiveButton(android.R.string.ok, new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d("Picker", timePicker.getCurrentHour() + ":"
                            + timePicker.getCurrentMinute());
                }
            })
            .setNegativeButton(android.R.string.cancel,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                int which) {
                            Log.d("Picker", "Cancelled!");
                        }
                    }).setView(timePicker).show();

Change DatePickerDialog with;

    final DatePicker datePicker = new DatePicker(this);
    datePicker.init(2012, 10, 5, null);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        datePicker.setCalendarViewShown(false);
    }

    new AlertDialog.Builder(this)
            .setTitle("Test")
            .setPositiveButton(android.R.string.ok, new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d("Picker", datePicker.getYear() + " "
                            + (datePicker.getMonth() + 1) + " "
                            + datePicker.getDayOfMonth());
                }
            })
            .setNegativeButton(android.R.string.cancel,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                int which) {
                            Log.d("Picker", "Cancelled!");
                        }
                    }).setView(datePicker).show();
Community
  • 1
  • 1
cirit
  • 490
  • 5
  • 10
2

According to Ankur Chaudhary's brilliant answer, just do the following:

new TimePickerDialog.OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker view, int setHour, int setMinute) {  
        if (view.isShown()) {
            // read the time here :)
        }
    }
};
Community
  • 1
  • 1
AbdelHady
  • 9,334
  • 8
  • 56
  • 83
  • How on earth would someone give this answer a down vote without even trying it, simply it is the best answer ever, just try it guys! – AbdelHady Dec 15 '15 at 11:25
1

OK, it looks like there's the similar bug for DatePicker here, but I had to modify my code by casting the Dialog to an AlertDialog before calling setButton()

((AlertDialog) d).setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
                    new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // Turn on your cancel flag here
                }
            });
Community
  • 1
  • 1
bryan
  • 798
  • 7
  • 18
0

Try playing with the activity focus(Activity.onWindowFocusChanged()). It suposed to change when the Dialog is pop out

Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216