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

Работающий Android 2.2 DatePicker

Android 4.1 DatePicker

Не работает средство выбора даты Android 4.1


person Nouran H    schedule 08.07.2012    source источник
comment
та же проблема Android 4.1 на эмуляторе 30 августа 2012 г., проголосуйте здесь code.google .com/p/android/issues/detail?id=34860   -  person Moak    schedule 30.08.2012
comment
возможный дубликат Jelly Bean DatePickerDialog --- есть ли способ отменить?   -  person Paul Lammertsma    schedule 11.11.2013


Ответы (4)


Попробуйте установить логическое значение для проверки двойного огня в одном и том же диалоговом окне. Что-то подобное:

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, и эта проверка также работает для них.

person lodlock    schedule 31.07.2012
comment
Переключите переменную fired обратно на false, чтобы после этого DatePicker продолжал работать. Кстати, проблема возникает и в диалогах TimePicker. - person Siklab.ph; 12.02.2013
comment
Эта обходная концепция также работает для диалоговых окон TimePicker, используя аналогичную проверку при создании. - person lodlock; 06.04.2013
comment
OMG - я сходил с ума, пытаясь понять, почему код в onDateSet из средства выбора даты не работает правильно, и после того, как некоторые toastMEssages поняли, что он срабатывает дважды. Большое вам спасибо - 11 часов попыток отладки, и это была эта чертова проблема. СПАСИБО!!!!! - person gbotha; 18.05.2013
comment
С удовольствием помогу чем смогу. - person lodlock; 18.09.2013
comment
Это неполное решение. Ошибка вызывает onDateSet() при нажатии кнопки "Готово" кнопку и когда диалоговое окно закрывается. Последнее также проблематично, потому что дата будет установлена, когда пользователь отменит действие (т. е. нажмет назад или коснется вне диалогового окна). Опубликованное здесь решение не решает эту проблему. - person Paul Lammertsma; 11.11.2013
comment
Этот ответ дает лучшее решение и подробно объясняет, в чем заключается основная проблема. - person Paul Lammertsma; 11.11.2013

Согласно блестящему ответу Анкура Чаудхари по аналогичной проблеме TimePickerDialog, если бы мы проверили внутри onDateSet, является ли данное представление isShown() или нет, оно решит всю проблему с минимальными усилиями, без необходимости расширения средства выбора или проверки каких-то отвратительных флагов в коде или даже проверки версии ОС, просто сделайте следующее:

public void onDateSet(DatePicker view, int year, int month, int day) {
    if (view.isShown()) {
        // read the date here :)
    }
}

и, конечно же, то же самое можно сделать для onTimeSet согласно ответу Анкура

person AbdelHady    schedule 16.03.2015

Я думаю, что это связано, сегодня я начал тестировать 4.1 и обнаружил, что некоторые события javascript, кажется, срабатывают дважды. В основном нажмите на данный момент. Странно, если я добавлю предупреждение, оно «иногда» срабатывает один раз. Поведение странным образом непоследовательно.

События javascript реагируют таким образом только на Android 4.1. iPhone выглядит нормально, как и все предыдущие версии Android, которые я пробовал до сих пор (включая 4.0.x).

Мне кажется, что это ошибка браузера или то, как он обрабатывает javascript, но это всего лишь предположение.

person Dan    schedule 13.07.2012
comment
Есть ли предложения, как решить эту ошибку? Есть обходные пути? :) - person Nouran H; 15.07.2012
comment
Ничего я не нашел до сих пор. Кроме того, в дополнение к вышесказанному кажется, что это происходит только при щелчке или касании. не все события. (когда у меня будет время) я создам отчет об ошибке в списке ошибок Android. - person Dan; 19.07.2012

Повторюсь: это подтвержденная ошибка в Android. Уже были предложены два обходных пути: сохранение состояния в переменной (экземпляра) или запрос диалогового окна, если оно isShown(). Но isShown() кажется ненадежным (согласно комментариям этого ответа, например), и сохранение состояния становится беспорядочным, если вы хотите повторно -show the dialog.
Лучшим решением будет сохранение состояния внутри самого диалога:

public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
    if (picker.getTag() == null) {
        picker.setTag("TAGGED");
        // Only gets called once per Dialog
    }
}

Это чисто и эффективно.

person leondepeon    schedule 29.04.2015