Android: эмулятор Android 4.1, вызывающий onDateSet дважды из диалога DatePicker

мое приложение отлично работало на моем эмуляторе Android 2.2. Затем я решил протестировать эмулятор Android 4.1. The 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

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


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

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

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


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

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

Это похоже на ошибку с браузером или способом его обработка JavaScript для меня, но это только предположение.


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

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

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