2012-07-08 6 views
18

La mia applicazione funzionava perfettamente sul mio emulatore Android 2.2. Ho quindi deciso di provare su un emulatore Android 4.1. Il DatePickerDialog sembra un po 'diverso e per qualche motivo quando premo "Fatto", il listener onDateSet() viene chiamato due volte e causa problemi nella mia applicazione.Android: Emulatore Android 4.1 Richiamo di onDateSet due volte da DatePicker Dialog

Lo so perché il registro indicato di seguito nel codice viene stampato due volte ogni volta che clicco su "Done"

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

+3

stesso numero Android 4.1 su emulatore 30 agosto 2012, votare qui https://code.google.com/p/android/issues/detail?id=34860 ​​ – Moak

+0

possibile duplicato di [Jelly Bean DatePickerDialog --- è lì un modo per cancellare?] (http: // StackOverflow.it/questions/11444238/jelly-bean-datepickerdialog-is-there-a-way-to-cancel) –

risposta

24

Provare a impostare un valore booleano per verificare un doppio incendio all'interno della stessa finestra di dialogo. Qualcosa di simile a:

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(); 

Questo problema doppio fuoco avviene anche con onTimeSet di un TimePickerDialog e questo controllo funziona anche per quelli.

+0

Sì, dovrebbe funzionare. Spero che risolvano presto questo problema. –

+1

Ripristina la variabile 'fired' su' false' in modo che DatePicker continui a funzionare in seguito. A proposito, il problema si verifica anche nelle finestre di dialogo TimePicker. –

+0

Questo concetto di work-around funziona anche per le finestre di dialogo TimePicker utilizzando un controllo "fired" simile al momento della creazione. – lodlock

0

Penso che questo sia collegato, ho iniziato a testare su 4.1 oggi e ho trovato che alcuni eventi di javascript sembrano sparare due volte. Principalmente clic al momento. Stranamente se aggiungo un avviso, "a volte" si attiva una volta. Il comportamento è stranamente incoerente.

Gli eventi javascript rispondono solo in questo modo su Android 4.1. iPhone sembra buono come tutte le precedenti versioni di Android che ho provato finora (incluso 4.0.x).

Sembra un errore con il browser o il modo in cui gestisce il javascript per me ma è solo un'ipotesi.

+0

Ci sono dei suggerimenti su come risolvere questo errore? Qualche soluzione alternativa? :) –

+0

Nulla che ho trovato finora. Anche in aggiunta a quanto sopra sembra solo essere su eventi click o touch. non tutti gli eventi (quando avrò un po 'di tempo) creerò un bug report sulla lista dei bug di Android. – Dan

1

Secondo Ankur Chaudhary di brillanti answer sulla simile TimePickerDialog problema, se abbiamo controllato all'interno onDateSet se la data vista isShown() o no, che possa risolvere l'intera questione con il minimo sforzo, senza la necessità di estendere il selettore o il controllo per alcune bandiere orribili in giro per il codice o addirittura di controllo per la versione del sistema operativo, basta fare il seguente:

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

e, naturalmente, lo stesso può essere fatto per onTimeSet secondo la risposta di Ankur

0

per ribadire: Thi s è un bug confermato in Android. Due soluzioni alternative sono già state suggerite, salvando lo stato in una variabile (istanza) o chiedendo la finestra di dialogo se è isShown(). Ma isShown() sembra inaffidabile (come ad esempio this answer's comments) e il salvataggio dello stato diventa complicato se si desidera visualizzare nuovamente la finestra di dialogo.
Una soluzione migliore è quella di salvare lo stato all'interno della finestra di dialogo in sé:

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

E 'pulito ed efficace.