Jelly Bean DatePickerDialog --- is there a way to cancel?
Solution 1
Note: Fixed as of Lollipop, source here. Automated class for use in clients (compatible with all Android versions) updated as well.
TL;DR: 1-2-3 dead easy steps for a global solution:
- Download this class.
- Implement
OnDateSetListener
in your activity (or change the class to suit your needs). -
Trigger the dialog with this code (in this sample, I use it inside a
Fragment
):Bundle b = new Bundle(); b.putInt(DatePickerDialogFragment.YEAR, 2012); b.putInt(DatePickerDialogFragment.MONTH, 6); b.putInt(DatePickerDialogFragment.DATE, 17); DialogFragment picker = new DatePickerDialogFragment(); picker.setArguments(b); picker.show(getActivity().getSupportFragmentManager(), "frag_date_picker");
And that's all it takes! The reason I still keep my answer as "accepted" is because I still prefer my solution since it has a very small footprint in client code, it addresses the fundamental issue (the listener being called in the framework class), works fine across config changes and it routes the code logic to the default implementation in previous Android versions not plagued by this bug (see class source).
Original answer (kept for historical and didactic reasons):
Bug source
OK, looks like it's indeed a bug and someone else already filled it. Issue 34833.
I've found that the problem is possibly in DatePickerDialog.java
. Where it reads:
private void tryNotifyDateSet() {
if (mCallBack != null) {
mDatePicker.clearFocus();
mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
}
}
@Override
protected void onStop() {
tryNotifyDateSet();
super.onStop();
}
I'd guess it could have been:
@Override
protected void onStop() {
// instead of the full tryNotifyDateSet() call:
if (mCallBack != null) mDatePicker.clearFocus();
super.onStop();
}
Now if someone can tell me how I can propose a patch/bug report to Android, I'd be glad to. Meanwhile, I suggested a possible fix (simple) as an attached version of DatePickerDialog.java
in the Issue there.
Concept to avoid the bug
Set the listener to null
in the constructor and create your own BUTTON_POSITIVE
button later on. That's it, details below.
The problem happens because DatePickerDialog.java
, as you can see in the source, calls a global variable (mCallBack
) that stores the listener that was passed in the constructor:
/**
* @param context The context the dialog is to run in.
* @param callBack How the parent is notified that the date is set.
* @param year The initial year of the dialog.
* @param monthOfYear The initial month of the dialog.
* @param dayOfMonth The initial day of the dialog.
*/
public DatePickerDialog(Context context,
OnDateSetListener callBack,
int year,
int monthOfYear,
int dayOfMonth) {
this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}
/**
* @param context The context the dialog is to run in.
* @param theme the theme to apply to this dialog
* @param callBack How the parent is notified that the date is set.
* @param year The initial year of the dialog.
* @param monthOfYear The initial month of the dialog.
* @param dayOfMonth The initial day of the dialog.
*/
public DatePickerDialog(Context context,
int theme,
OnDateSetListener callBack,
int year,
int monthOfYear,
int dayOfMonth) {
super(context, theme);
mCallBack = callBack;
// ... rest of the constructor.
}
So, the trick is to provide a null
listener to be stored as the listener, and then roll your own set of buttons (below is the original code from #1, updated):
DatePickerDialog picker = new DatePickerDialog(
this,
null, // instead of a listener
2012, 6, 15);
picker.setCancelable(true);
picker.setCanceledOnTouchOutside(true);
picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Picker", "Correct behavior!");
}
});
picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Picker", "Cancel!");
}
});
picker.show();
Now it will work because of the possible correction that I posted above.
And since DatePickerDialog.java
checks for a null
whenever it reads mCallback
(since the days of API 3/1.5 it seems --- can't check Honeycomb of course), it won't trigger the exception. Considering Lollipop fixed the issue, I'm not going to look into it: just use the default implementation (covered in the class I provided).
At first I was afraid of not calling the clearFocus()
, but I've tested here and the Log lines were clean. So that line I proposed may not even be necessary after all, but I don't know.
Compatibility with previous API levels (edited)
As I pointed in the comment below, that was a concept, and you can download the class I'm using from my Google Drive account. The way I used, the default system implementation is used on versions not affected by the bug.
I took a few assumptions (button names etc.) that are suitable for my needs because I wanted to reduce boilerplate code in client classes to a minimum. Full usage example:
class YourActivity extends SherlockFragmentActivity implements OnDateSetListener
// ...
Bundle b = new Bundle();
b.putInt(DatePickerDialogFragment.YEAR, 2012);
b.putInt(DatePickerDialogFragment.MONTH, 6);
b.putInt(DatePickerDialogFragment.DATE, 17);
DialogFragment picker = new DatePickerDialogFragment();
picker.setArguments(b);
picker.show(getActivity().getSupportFragmentManager(), "fragment_date_picker");
Solution 2
I'm gonna add my own riff on the solution David Cesarino posted, in case you're not using Fragments, and want an easy way to fix it in all versions (2.1 thru 4.1):
public class FixedDatePickerDialog extends DatePickerDialog {
//I use a Calendar object to initialize it, but you can revert to Y,M,D easily
public FixedDatePickerDialog(Calendar dateToShow, Context context, OnDateSetListener callBack) {
super(context, null, dateToShow.get(YEAR), dateToShow.get(MONTH), dateToShow.get(DAY_OF_MONTH));
initializePicker(callBack);
}
public FixedDatePickerDialog(Calendar dateToShow, Context context, int theme,
OnDateSetListener callBack) {
super(context, theme, null, dateToShow.get(YEAR), dateToShow.get(MONTH), dateToShow.get(DAY_OF_MONTH));
initializePicker(callBack);
}
private void initializePicker(final OnDateSetListener callback) {
try {
//If you're only using Honeycomb+ then you can just call getDatePicker() instead of using reflection
Field pickerField = DatePickerDialog.class.getDeclaredField("mDatePicker");
pickerField.setAccessible(true);
final DatePicker picker = (DatePicker) pickerField.get(this);
this.setCancelable(true);
this.setButton(DialogInterface.BUTTON_NEGATIVE, getContext().getText(android.R.string.cancel), (OnClickListener) null);
this.setButton(DialogInterface.BUTTON_POSITIVE, getContext().getText(android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
picker.clearFocus(); //Focus must be cleared so the value change listener is called
callback.onDateSet(picker, picker.getYear(), picker.getMonth(), picker.getDayOfMonth());
}
});
} catch (Exception e) { /* Reflection probably failed*/ }
}
}
Solution 3
Until the bug will be fixed I suggest not to 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();
Solution 4
The one for TimePicker based on the solution by David Cesarino , "TL;DR: 1-2-3 dead easy steps for a global solution"
TimePickerDialog does not provide the functionality like DatePickerDialog.getDatePicker. So, OnTimeSetListener listener has to be provided. Just to keep the similarity with DatePicker workaround solution, I have maintained the old mListener concept. You can change it if you need to.
Calling and Listener is same as original solution. Just include
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
extend parent class,
... implements OnDateSetListener, OnTimeSetListener
Implement
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
...
}
example calling
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
Bundle b = new Bundle();
b.putInt(TimePickerDialogFragment.HOUR, hour);
b.putInt(TimePickerDialogFragment.MINUTE, minute);
DialogFragment picker = new TimePickerDialogFragment();
picker.setArguments(b);
picker.show(getSupportFragmentManager(), "frag_time_picker");
(Updated to handle cancel)
public class TimePickerDialogFragment extends DialogFragment {
public static final String HOUR = "Hour";
public static final String MINUTE = "Minute";
private boolean isCancelled = false; //Added to handle cancel
private TimePickerDialog.OnTimeSetListener mListener;
//Added to handle parent listener
private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
if (!isCancelled)
{
mListener.onTimeSet(view,hourOfDay,minute);
}
}
};
//
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mListener = (TimePickerDialog.OnTimeSetListener) activity;
}
@Override
public void onDetach() {
this.mListener = null;
super.onDetach();
}
@TargetApi(11)
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle b = getArguments();
int h = b.getInt(HOUR);
int m = b.getInt(MINUTE);
final TimePickerDialog picker = new TimePickerDialog(getActivity(), getConstructorListener(), h, m,DateFormat.is24HourFormat(getActivity()));
//final TimePicker timePicker = new TimePicker(getBaseContext());
if (hasJellyBeanAndAbove()) {
picker.setButton(DialogInterface.BUTTON_POSITIVE,
getActivity().getString(android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
isCancelled = false; //Cancel flag, used in mTimeSetListener
}
});
picker.setButton(DialogInterface.BUTTON_NEGATIVE,
getActivity().getString(android.R.string.cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
isCancelled = true; //Cancel flag, used in mTimeSetListener
}
});
}
return picker;
}
private boolean hasJellyBeanAndAbove() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}
private TimePickerDialog.OnTimeSetListener getConstructorListener() {
return hasJellyBeanAndAbove() ? mTimeSetListener : mListener; //instead of null, mTimeSetListener is returned.
}
}
Solution 5
According to Ankur Chaudhary's brilliant answer on the similar TimePickerDialog
issue, if we checked inside onDateSet
if the given view isShown()
or not, it will solve the whole issue with the minimal effort, with no need for extending the picker or checking for some hideous flags going around the code or even checking for the OS version, just do the following:
public void onDateSet(DatePicker view, int year, int month, int day) {
if (view.isShown()) {
// read the date here :)
}
}
and of course the same can be done for onTimeSet
as per Ankur's answer
Related videos on Youtube
davidcesarino
Ubuntu and Dart. Quality over quantity, please! Keep your SNR high.
Updated on March 03, 2020Comments
-
davidcesarino about 4 years
--- Note to moderators: Today (July 15), I've noticed that someone already faced this problem here. But I'm not sure if it's appropriate to close this as a duplicate, since i think I provided a much better explanation of the issue. I'm not sure if I should edit the other question and paste this content there, but I'm not comfortable changing someone else's question too much. ---
I have something weird here.
I don't think the problem depends on which SDK you build against. The device OS version is what matters.
Problem #1: inconsistency by default
DatePickerDialog
was changed (?) in Jelly Bean and now only provides a Done button. Previous versions included a Cancel button, and this may affect user experience (inconsistency, muscle memory from previous Android versions).Replicate: Create a basic project. Put this in
onCreate
:DatePickerDialog picker = new DatePickerDialog( this, new OnDateSetListener() { @Override public void onDateSet(DatePicker v, int y, int m, int d) { Log.d("Picker", "Set!"); } }, 2012, 6, 15); picker.show();
Expected: A Cancel button to appear in the dialog.
Current: A Cancel button does not appear.
Screenshots: 4.0.3 (OK) and 4.1.1 (possibly wrong?).
Problem #2: wrong dismiss behavior
Dialog calls whichever listener it should call indeed, and then always calls
OnDateSetListener
listener. Canceling still calls the set method, and setting it calls the method twice.Replicate: Use #1 code, but add code below (you'll see this solves #1, but only visually/UI):
picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.d("Picker", "Cancel!"); } });
Expected:
- Pressing the BACK key or clicking outside the dialog should do nothing.
- Pressing "Cancel" should print Picker Cancel!.
- Pressing "Set" should print Picker Set!.
Current:
- Pressing the BACK key or clicking outside the dialog prints Picker Set!.
- Pressing "Cancel" prints Picker Cancel! and then Picker Set!.
- Pressing "Set" prints Picker Set! and then Picker Set!.
Log lines showing the behavior:
07-15 12:00:13.415: D/Picker(21000): Set! 07-15 12:00:24.860: D/Picker(21000): Cancel! 07-15 12:00:24.876: D/Picker(21000): Set! 07-15 12:00:33.696: D/Picker(21000): Set! 07-15 12:00:33.719: D/Picker(21000): Set!
Other notes and comments
- Wrapping it around a
DatePickerFragment
doesn't matter. I simplified the problem for you, but I've tested it.
-
Michael Hampton almost 12 yearsCongratulations, you seem to have found a bug in Android. You can report it here.
-
Lumii over 11 yearsVery well written bug report. I can understand it completely without having to test run the code.
-
Bradley over 11 yearsI urge everyone to vote this issue up! Issue 34833
-
Karthik Balakrishnan almost 11 yearsCouldn't you just override the button function to act like it was dismissed due to touch outside the dialog?
-
davidcesarino almost 11 years@Torcellite not sure what you mean. The behavior is not dependent on how you dismiss the dialog (i.e., if by clicking outside or using a button, or back), since the listener is called whenever the dialog is stopped. See my answer below, when I quote the Android sources. Thus, the point is to tell the framework to not call the listener somehow, and the framework will not call only when it detects a null listener, hence why the class I wrote selectively pass the listener in the constructor or later on, depending on which API you are. Transparently to the client, of course.
-
Karthik Balakrishnan almost 11 yearsMy point is, instead of working so much why couldn't you just make Android think that the click on the
Done
button was a click outside the dialog, thereby getting only one alarm anyway? It's a rough hack, but very easy. -
davidcesarino almost 11 years@Torcellite Oh, I see... If you fix "Back" behavior (either a dialog back or the system back), I guess you could. But, personally, I think that, by the time I filled all my client classes with the same calls everywhere just to "hack around" the bug in a very obscure manner ("why does this 'Done' button do nothing?"), it would be minimal effort to just put everything in a reusable class that can effortlessly replace the framework one, to begin with. Not only I just fixed the fundamental issue (
onStop
behavior), but also have superior readability in my clientS. I saved myself future time. -
Xavier Egea almost 11 yearsJust to add another problem using TimePicker I have found, is the difference in buttons position between 4.0.3 version and the old 2.3.3 where the cancel button is on the right and the set button on the left. I haven't tested in version 3.x, but I think this hadn't been fixed till 4.0.x version. As has been posted in the answer, this fix has been broken in the 4.1.x setting one "Set" button and no possibility to cancel or dismiss.
-
davidcesarino almost 11 years@XavierEgea Not sure I understand what you mean... I thought they purposely changed the button position for usability reasons (well, at least for right handed people I guess). About 2.x and below, it's better to not mess with it and rely on the system defaults where muscle memory is a factor to consider for the user.
-
Xavier Egea almost 11 years@DavidCesarino After my comment I have tested a little bit more on 2.x devices and I realised (correct please if I'm wrong) that in old versions the default cancel button was on the right, at least in the System applications that I've tested. So, you are right, it's better to rely on System Defaults to avoid changing completely the application. Thanks
-
davidcesarino almost 11 yearsNo problem! That's what I meant as well: before, it was Ok-Cancel, like in desktop systems. After ICS, it's Cancel-OK for usability reasons. Additionally, let's remember that this applies to all dialogs if you use the standard POSITIVE and NEGATIVE identifiers. It is not exclusive to DatePicker or TimePicker dialogs.
-
erdomester over 9 yearsBug is still open after 2 years...unbelievable.
-
CommonsWare almost 12 yearsAwesome job on the research! Sad that it was necessary, but awesome nonetheless.
-
span almost 12 yearsVery nice! I've been hammering my head against the wall on this issue that was updating my textfields and calling/not calling the correct callbacks. Thank you! I wonder if the suggested workaround is "future proof" or if you think it will cause problems when the bug is fixed?
-
davidcesarino almost 12 yearsGood question. I don't think anyone except Google can guarantee anything. I still think they should (and will) revert back to the "up-to-ICS" behavior at some point in the future. About future-proofing, I can only see the
null
listener being the possible point of failure. But considering legacy support for the API, I don't think they would (ever?) remove that null check, which in case you'd be fine. Please note, however, that this is a minimal example for a working solution. I'm NOT using it in production code, and I've made my ownDatePickerDialogFragment
since then. -
davidcesarino almost 12 yearsBtw, you can get what I'm currently using here.
-
Romain Guidoux over 11 years@DavidCesarino Nice workaround, but how do you get the date on an Android 2.x device ? (there is no getDatePicker() method on the DatePickerDialog)
-
davidcesarino over 11 years@RomainGuidoux see updated answer at the end. The class in the link has the smarts to only call that method in jelly bean. On anything below it will bypass that and use the default system implementation, routing the system call for ondateset to your activity. It's just that in jelly bean it takes additional measures (avoiding the bug) before routing the callback, and that involves calling that honeycomb+ method. But again, only in JB.
-
davidcesarino over 11 yearsJust remembering: if you're hardwiring the button names to ok and cancel, it's probably better to use the standard
android.R.string.ok
andandroid.R.string.cancel
fields, instead of user's own. And thanks for the reply. -
dmon over 11 yearsAh, nice, I haven't noticed they provided OK and Cancel text. Thanks!
-
Bill Phillips over 11 yearsAwesome work here. I don't have the words for how ridiculous this issue is.
-
Kishore over 11 yearsgetting nullpointer exception at super(context, theme, null, dateToShow.get(YEAR), dateToShow.get(MONTH), dateToShow.get(DAY_OF_MONTH));
-
dmon over 11 yearsErrr... are you passing a null
dateToShow
? The other null there is actually the "fix" so that should be there. Which version are you on? -
Adil Malik about 11 yearsI have on confusion now how can I get the selected Month, Day and Year in onClick method of 'Set' ?
-
Adil Malik about 11 yearscan you please let me know which
import
did you have forField
? I am having 6 options and none of them worked. -
davidcesarino about 11 years@AdilMalik You mean in the class I'm using? It routes the selected data to your Activity through the onDateSet call. As you can see, the Activity in which you use the dialog implements onDateSetListener. Of course, you're free to change it, but I think that way it works well (without the need to keep track of changes and everything).
-
davidcesarino about 11 yearsPlain and simple, it does not work the way you tell.
timePickerListener
is still called regardless of what you do in your dialog. I don't even need to test to know that, you just need to look at the sources: if you do not set it tonull
,tryNotifyTimeSet()
will call the listener'sonTimeSet()
both in itsonClick()
andonStop()
. -
davidcesarino about 11 yearsIn other words, do not let the native class hold a reference to your listener (i.e., passing it in the constructor). How you deal with buttons is irrelevant.
-
Crocodile about 11 yearsHi David, You didn't test this and you assumed it wont work. This is the exact piece of code I am currently using in my app and it works like a champ.
-
davidcesarino about 11 years1) I never said it didn't work. I said it didn't work the way you said it did. Please read again. 2) you violated LSP and SRP, wasting man-hours to needlessly change all your entire client logic that didn't need any changes to begin with. 3) your answer addresses the question, yes, otherwise I'd flag it for removal as "not an answer", but 4) your answer is still (sorry about it) very inefficient and does not address the fundamental design issue (listener called), hence only the downvote. 6) you disabled back and made it a modal window to force the boolean. So, 6 serious issues there!
-
davidcesarino almost 11 yearsOnce again, just like I told the other guy before you, this does not solve the bug. I don't want to sound rude, but you guys should be testing your own solution before posting here... just to prove my point, use your code and let the user press back to cancel the dialog and see what I mean. The cause of the bug is
onStop
calling the method when it shouldn't... it firing twice is a consequence of the bug. -
davidcesarino almost 11 yearsIf I wasn't clear enough, let me be: pressing back to cancel the dialog calls
onDateSet
. Thus, broken. -
chamikaw almost 11 yearsThank you for showing the error. I edit the answer so that it will work with back button. Your answer is working but DatePicker dp = picker.getDatePicker(); is not working with TimePickers since getTimePicker() method is not added. So this would be a valid answer
-
lokoko over 10 yearsHow about TimePickerDialog ? It seems like TimePickerDialog does not have a getTimePicker()
-
davidcesarino over 10 years@lokoko I know. I didn't think about it yet because I don't need it.
-
DDD over 10 yearsEven if an ActionBar is used then this might be an acceptable workaround if you never hide/show the ActionBar. To make things extra safe you can override onStart to do nothing as well (then the calls for the animation would be safely unhooked). And even if you do hide/show it, it's just the animation that's disabled.
-
dmon over 10 yearsIt's the reflection Field, so
import java.lang.reflect.Field
-
erdomester over 9 yearsThis worked for me wonderfully. Easy to understand, easy to implement! Tested on 4.4
-
Daniel Ryan over 9 years@AbdelHady your code edit was incorrect but I have edited it to make it more clear. There is no need to add a "isJellyBeanOrAbove()" method, there is no advantage, just adds unnecessary complexity. Calling resetFired is cheap.
-
AbdelHady over 9 yearsthe code here is incorrect, because
onDateSet
will be called once when the dialog is being closed by any means, and if that mean was to set the time then it will be fired again, so we need to catch the second call, not the first one as you did, -
AbdelHady over 9 yearsConcerning
isJellyBeanOrAbove()
, versions lower than Jellybean don't have the bug that this whole question is all about, & considering we want to catch the second call, the code won't run unless we make this check, believe me, I've tried my code on Emulators & real devices (with different versions) several times & it is working like a charm -
AbdelHady over 9 yearsHow we are trying to skip the second run?!!, I've tried it several times, when closing the dialog by any means
onDateSet
will be called once, but when choosing "done" or "set" then it will be called twice. Therefor we need to skip only the first one, so if it is called twice then & only then we have the correct date -
Daniel Ryan over 9 yearsI'm not sure if that is worth a downvote. I posted this 2 years ago, this has been in our commercial application since then working just fine. No bugs reported by our QA teams or our thousands of users. This is meant to be a simple answer that people can extend. Call "resetFired" when you want it to fire again.
-
Daniel Ryan over 9 yearsIn our app "isJellyBeanOrAbove" is not needed. The app will just work fine in all versions if you call "resetFired" in the correct areas.
-
Shadow over 9 yearshi but this works for first time. how to handle for second time when user not selected by clicking done button in date and clicked outside of date picker dialog?
-
Daniel Ryan over 9 yearsBy calling resetFired when you open the dialog again.
-
AbdelHady about 9 yearsIt is not working for me when trying it on s3 API 18
-
stuckj about 9 yearsThis is pretty similar to The Sea's answer above.
-
hiew1 over 8 yearsBest answer out of all the other!
-
southerton over 7 yearsFor TimePickerDialog there is another workaround stackoverflow.com/a/39636443/311060