Is there a way to use undo in Android JellyBean TimePickerDialog?

As far as I know, versions prior to Jelly Beans had Set and Cancel buttons when using TimePickerDialog . Jelly Beans only has a Done button.

I could just leave the Done button and close the dialog by clicking outside the dialog, but my onTimeSetListener is called when Done is clicked or outside the dialog.

So, I have found https://stackoverflow.com/a/168298/ which describes that an error occurs when using DatePickerDialog . To fix the problem with DatePickerDialog , during initialization I had to set onDateSetListener to null and implement my own buttons for processing BUTTON_POSITIVE (Set) and BUTTON_NEGATIVE (Cancel) onClick. This is normal because when the Set button is called, I can access DatePicker values ​​such as

 int yearPicked = dateDlg.getDatePicker().getYear(); int monthPicked = dateDlg.getDatePicker().getMonth(); int dayPicked = dateDlg.getDatePicker().getDayOfMonth(); 

Therefore, there is no need to use onDateSetListener , but if I did, it would be called again when I click Set or Cancel.

I tried using TimePickerDialog in the same way, but the problem is that inside the BUTTON_POSITIVE onClick method I cannot access the hours and minutes as before, because TimePickerDialog does not provide TimePicker since DatePickerDialog provides DatePicker . And again, if I were to use onTimeSetListener , it would be called by clicking something.

 Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); int min = cal.get(Calendar.MINUTE); final TimePickerDialog timeDlg = new TimePickerDialog(PreferencesActivity.this, null, hour, min, true); // Make the Set button timeDlg.setButton(DialogInterface.BUTTON_POSITIVE, "Set", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) { // CANNOT ACCES THE VALUES Toast.makeText(PreferencesActivity.this, "Set", Toast.LENGTH_SHORT).show(); } } }); // Set the Cancel button timeDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_NEGATIVE) { Toast.makeText(PreferencesActivity.this, "Cancel", Toast.LENGTH_SHORT).show(); } } }); timeDlg.show(); 
+6
source share
2 answers

According to your comment, it should be easy enough to protect the OnTimeSetListener with a boolean so that your logic does not start if you click Cancel.

I had a quick game with your code, and the following seemed to work well:

 private boolean mIgnoreTimeSet = false; final TimePickerDialog timeDlg = new TimePickerDialog(PreferencesActivity.this, PreferencesActivity.this, hour, min, true); // Make the Set button timeDlg.setButton(DialogInterface.BUTTON_POSITIVE, "Set", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mIgnoreTimeSet = false; // only manually invoke OnTimeSetListener (through the dialog) on pre-ICS devices if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) timeDlg.onClick(dialog, which); Toast.makeText(getApplicationContext(), "Set", Toast.LENGTH_SHORT).show(); } }); // Set the Cancel button timeDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "Cancel", Toast.LENGTH_SHORT).show(); mIgnoreTimeSet = true; dialog.cancel(); } }); timeDlg.show(); @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { if (mIgnoreTimeSet) return; // get the values here - this will only run if 'Set' was clicked } 

For example, I assumed that your PreferencesActivity implements OnTimeSetListener . Since onTimeSet(...) is called after onClick(...) , you can simply toggle a boolean that will determine if something needs to be done with the values ​​in the callback or just ignore them.

I have to agree that this is not ideal, but at least functional. After the holidays, I will try again to look at the "best" solution.

One alternative would be to use reflection to get a handle to the built-in TimePicker widget, but more likely to break in future releases of Android.


// Edit: A Potential Alternative? (not verified)

The second alternative, which may be a bit cleaner: TimePickerDialog and overwrite the public method (empty):

 public void onTimeChanged(TimePicker view, int hourOfDay, int minute) 

There, keep track of the user-specified hour of the day and minute, and implement two recipients that return them. Then, get these values ​​only from the dialog box if the "positive" button is pressed, but just skip the "Cancel" button. Basically, you no longer need the OnTimeSetListener , and therefore it doesn't matter if it is ever called or not.


// Edit2: support for ICS pre-connected devices

After receiving a few comments about the proposed solution that did not work on devices that preceded ICS, I made a small change to the above code - even hard, it did not fit the original question.

The main difference between devices before ICS and post-ICS is that the OnTimeSetListener does not start automatically after the onClick() dialog box method is launched. A simple workaround for this is to call the onClick() method in a dialog box, which then calls the listener. In the above solution, I added version code checking, because otherwise your listener will be called twice on devices after ICS, which can lead to unwanted side effects.

The behavior of Android 2.1-update1 and Android 4.2.2 was tested and confirmed.

+8
source

I found this thread when I was experiencing the same “Button Only” issue with the TimePickerDialog for Jelly Bean on my Nexus 7 (my Nexus One, Gingerbread, with Set and Cancel buttons for the same TimePickerDialog). However, it turned out that with the next update 4.3 Jelly Bean on my Nexus 7 (Build Number JWR66Y) the correct Set and Cancel buttons will return.

However, while investigating this problem, I came across this fooobar.com/questions/41429 / ... , which pretty carefully describes the big problems with DatePickerDialog (with similar problems mentioned for TimePickerDialog in the indicated error report) and offers a solution.

Remember that the use of these dialogs should be carefully considered, since they do not work correctly in some versions of Android (the solution offered in the aforementioned stream is not used “in production code”, according to its author).

+1
source

All Articles