Today I was trying to use the TimePickerDialog
but I noticed a couple of flaws.
The API I'm using is 18.
Anyone else has experienced these problems? How did you solve them?
You hould use already given method of View class:
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
if (view.isShown()) {
// This method will return true only once...
}
}
};
Faced the exact same issue today. Could not figure out why this was happening, but found a simple solution:
Method onTimeSet() is called once when dialog is dismissed and is called twice when Done button is clicked. Either way, there is one unwanted call to onTimeSet(). So I decided to always ignore the first call.
Here's the code:
Calendar mcurrentTime = Calendar.getInstance();
int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
int minute = mcurrentTime.get(Calendar.MINUTE);
TimePickerDialog mTimePicker;
mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener()
{
int callCount = 0; //To track number of calls to onTimeSet()
@Override
public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute)
{
if(callCount == 1) // On second call
{
timeString = selectedHour + ":" + selectedMinute + ":00";
Log.d("TEST", "Chosen time : "+ timeString);
}
callCount++; // Incrementing call count.
}
}, hour, minute, true);
mTimePicker.setTitle("Pick Time");
mTimePicker.show();
To reiterate: This is a confirmed bug in Android for multiple Dialog types. Two workarounds have already been suggested, saving the state in a (instance) variable or asking the Dialog if it isShown()
. But isShown()
seems to be unreliable in Android 4.0.4 and saving the state gets messy if you want to re-show the dialog.
A better solution is to save the state inside the Dialog itself, because it is the same instance that calls the method:
public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
if (picker.getTag() == null) {
picker.setTag("TAGGED");
// Only gets called once per Dialog
}
}
It's clean and effective.
Using count to avoid it. when TimePickDialog was selected more than twice, it should also work well.
TimePickerDialog tpd = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
int count = 0;
@Override
public void onTimeSet(TimePicker view, int setHour, int setMinute) {
if(count % 2 == 0) {
//set time here
}
count++;
} }, hour, minute, true);
Thanks to Tony for posting a workaround. This works for most of the time but not always. We had released our app with this workaround (along with version checks); however this solution failed on Samsung Galaxy Note GT-8000 (Android 4.4.2). Default 4.4.2 devices have this bug and solution works however Samsung seems to have fixed this issue in 4.4.2 release so onTimeSet() is called only once that we ignore and second call never happened.
We are posting a solution that we applied today. Though I am not happy with the solution as it is another hack/workaround but it may help in scenarios where version check doesn't help and OEMs merge selective fixes.
Our earlier implementation was
if((android.os.Build.VERSION.SDK_INT >=
Build.VERSION_CODES.ICE_CREAM_SANDWICH) &&
(android.os.Build.VERSION.SDK_INT <
Build.VERSION_CODES.LOLLIPOP)){
if(ccount == 1){
// Do Your Processing
count = 0;
}else{
// Ignore event. Bug in Android API
count++;
}
}else{
// Do Your Processing
}
Our New Implementation is
if((android.os.Build.VERSION.SDK_INT >=
Build.VERSION_CODES.ICE_CREAM_SANDWICH) &&
(android.os.Build.VERSION.SDK_INT <
Build.VERSION_CODES.LOLLIPOP)){
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stacktrace[4];
String methodName = e.getMethodName();
if(methodName.equals("onClick")){
// Do Your Processing
}else{
// Ignore event. Bug in Android API
}
}else{
// Do Your Processing
}
Hope it may help others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With