OnTimeSet вызывается также при отключении TimePickerDialog
Сегодня я пытался использовать TimePickerDialog
, но я заметил пару недостатков.
- OnTimeSet вызывается также при отклонении диалога (например, нажатием на внешнюю сторону)
- OnTimeSet вызывается дважды, когда пользователь нажимает кнопку "Готово"
API, который я использую, - 18.
Кто-нибудь еще испытал эти проблемы? Как вы их решили?
Ответы
Ответ 1
Сегодня столкнулся с той же проблемой. Не удалось выяснить, почему это происходит, но найдено простое решение:
Метод onTimeSet() вызывается один раз, когда диалог отклоняется и вызывается дважды при нажатии кнопки Done. В любом случае, есть один нежелательный вызов onTimeSet(). Поэтому я решил всегда игнорировать первый звонок.
Здесь код:
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();
Ответ 2
Вы можете использовать уже данный метод класса View:
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
if (view.isShown()) {
// This method will return true only once...
}
}
};
Ответ 3
Повторить: это подтвержденная ошибка в Android для нескольких типов Dialog. Два метода обхода уже предложены, сохраняя состояние в переменной (экземпляре) или запрашивая диалоговое окно, если оно isShown()
. Но isShown()
кажется ненадежным в Android 4.0.4, и сохранение состояния становится беспорядочным, если вы хотите повторно показать диалог.
Лучшим решением является сохранение состояния внутри самого диалогового окна, поскольку это тот же самый экземпляр, который вызывает метод:
public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
if (picker.getTag() == null) {
picker.setTag("TAGGED");
// Only gets called once per Dialog
}
}
Он чист и эффективен.
Ответ 4
Использование count, чтобы избежать его. когда TimePickDialog был выбран более двух раз, он также должен хорошо работать.
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);
Ответ 5
Спасибо Тони за опубликование обходного пути. Это работает большую часть времени, но не всегда. Мы выпустили наше приложение с этим обходным решением (наряду с проверками версий); однако это решение не удалось выполнить в Samsung Galaxy Note GT-8000 (Android 4.4.2). У устройств по умолчанию 4.4.2 эта ошибка и решение работают, однако Samsung, похоже, исправил эту проблему в версии 4.4.2, поэтому onTimeSet() вызывается только один раз, который мы игнорируем, а второй вызов никогда не происходил.
Мы публикуем решение, которое мы применяем сегодня. Хотя я не доволен решением, поскольку это еще один хак/обходной путь, но он может помочь в сценариях, где проверка версии не помогает, а OEM-производители объединяют выборочные исправления.
Наша предыдущая реализация была
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
}
Наша новая реализация
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
}
Надеюсь, это поможет другим.