Android: эмулятор Android 4.1 Вызов onDateSet дважды из диалогового окна DatePicker
Мое приложение отлично работало на моем эмуляторе Android 2.2. Затем я решил протестировать эмулятор Android 4.1. DatePickerDialog
выглядит немного по-другому и по какой-то причине, когда я нажимаю "Готово", прослушиватель onDateSet()
дважды вызывается и вызывает проблемы в моем приложении.
Я знаю это, потому что журнал, показанный ниже в коде, печатается дважды, когда я нажимаю "Готово"
mDateSetListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Log.v("onDateSet", "ENTERED");
//rest of code...
}};
Android 2.2 DatePicker
![Working Android 2.2 DatePicker]()
Android 4.1 DatePicker
![Not Working Android 4.1 DatePicker]()
Ответы
Ответ 1
Попробуйте установить логическое значение для проверки двойного огня в том же диалоговом окне. Нечто похожее на:
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, 1);
final DatePickerDialog dateDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
boolean fired = false;
public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
Log.i("PEW PEW", "Double fire check");
if (fired) {
Log.i("PEW PEW", "Double fire occured. Silently-ish returning");
return;
} else {
//first time fired
fired = true;
}
//Normal date picking logic goes here
}
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
dateDialog.show();
Эта проблема с двойным огнем также происходит с onTimeSet TimePickerDialog, и эта проверка также работает для них.
Ответ 2
Согласно Ankur Chaudhary блестящий ответ по аналогичной проблеме TimePickerDialog
, если мы проверили внутри onDateSet
, если данное представление isShown()
или нет, оно будет решить всю проблему с минимальными усилиями, без необходимости расширять сборщик или проверять некоторые отвратительные флаги, идущие вокруг кода или даже проверять версию ОС, просто выполните следующие действия:
public void onDateSet(DatePicker view, int year, int month, int day) {
if (view.isShown()) {
// read the date here :)
}
}
и, конечно же, это можно сделать для onTimeSet
согласно ответу Ankur
Ответ 3
Я думаю, что это связано, я начал тестировать на 4.1 сегодня и обнаружил, что некоторые события javascript, похоже, срабатывают дважды. В данный момент в основном нажмите.
Странно, если я добавлю предупреждение, он "иногда" срабатывает один раз.
Поведение странно непоследовательно.
События javascript реагируют таким образом на Android 4.1. iPhone кажется прекрасным, как и все предыдущие версии Android, которые я пробовал до сих пор (включая 4.0.x).
Похоже на ошибку в браузере или на то, как он обрабатывает javascript для меня, но это просто предположение.
Ответ 4
Повторить: это подтвержденная ошибка в Android. Два метода обхода уже предложены, сохраняя состояние в переменной (экземпляре) или запрашивая диалоговое окно, если оно isShown()
. Но isShown()
кажется ненадежным (например, этот ответ), и сохранение состояния становится беспорядочным, если вы хотите повторно показать диалог.
Лучшим решением является сохранение состояния внутри самого диалогового окна:
public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
if (picker.getTag() == null) {
picker.setTag("TAGGED");
// Only gets called once per Dialog
}
}
Он чист и эффективен.