2012-12-06 20 views
13

Ho questo problema con la mia app quando chiamo per mostrare una finestra di dialogo, viene chiamato due volte in qualche modo. Questo succede solo con Android 4.1 e versioni successive. La versione inferiore funziona bene quindi non penso che sia un problema di codice.Le finestre di dialogo 4.1.2 Android sono chiamate due volte

Hai sentito \ riscontrato questo problema in precedenza?

qui il codice:

Button edit = (Button) ad.findViewById(R.id.editBtn); 
     edit.setTypeface(roboto); 
     edit.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       setDate(); 
       ad.dismiss(); 
      } 
     }); 

     ad.show(); 

     ad.setOnDismissListener(new OnDismissListener() { 

      @Override 
      public void onDismiss(DialogInterface dialog) { 
       shiftsActivity.setPressed(true); 

      } 
     }); 
    } 

    public void setDate() { 
    // Initialize and open the set date dialog 
    DatePickerDialog setDateDialog = new DatePickerDialog(Shifts.this, 
      datePickerListener, dateAndTime.get(Calendar.YEAR), 
      dateAndTime.get(Calendar.MONTH), 
      dateAndTime.get(Calendar.DAY_OF_MONTH)); 

    setDateDialog.setTitle("Set Date"); 
    setDateDialog.show(); 

} 

public void setStartTime() { 

    TimePickerDialog setStartTimeDialog = new TimePickerDialog(Shifts.this, 
      startTimePicker, dateAndTime.get(Calendar.HOUR), 
      dateAndTime.get(Calendar.MINUTE), true); 

    setStartTimeDialog.setTitle("Started At:"); 
    setStartTimeDialog.show(); 

} 

public void setEndTime() { 

    TimePickerDialog setEndTimeDialog = new TimePickerDialog(Shifts.this, 
      setEndTime, dateAndTime.get(Calendar.HOUR), 
      dateAndTime.get(Calendar.MINUTE), true); 
    setEndTimeDialog.setTitle("Ended:"); 
    setEndTimeDialog.show(); 
} 

TimePickerDialog.OnTimeSetListener startTimePicker = new TimePickerDialog.OnTimeSetListener() { 

    @Override 
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 
     startIntHours = hourOfDay; 
     startIntMinutes = minute; 
     editStartTime = String.format("%02d", hourOfDay) + ":" 
       + String.format("%02d", minute); 
     setEndTime(); 

    } 
}; 

TimePickerDialog.OnTimeSetListener setEndTime = new TimePickerDialog.OnTimeSetListener() { 

    @Override 
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 

     finishIntHours = hourOfDay; 
     finsihIntMinutes = minute; 

     if (finishIntHours < startIntHours) { 
      finishIntHours = finishIntHours + Utility.HOURS_TIME_UNIT; 
     } 

     if (finsihIntMinutes < startIntMinutes) { 
      finsihIntMinutes = finsihIntMinutes + Utility.MINUTES_TIME_UNIT; 
     } 

     totalHours = finishIntHours - startIntHours; 
     totalMinutes = finsihIntMinutes - startIntMinutes; 
     Log.i("TotalHours in time picker", "" + totalHours); 
     Log.i("Totalminute in time picker", "" + totalMinutes); 

     editEndTime = String.format("%02d", hourOfDay) + ":" 
       + String.format("%02d", minute); 

     replace(Shifts.view, Shifts.position); 

    } 
}; 
+1

La parte interessante è: dove si 'setStartTime' chiamato – zapl

+0

su 4.0.3 funziona normale – Talha

+0

Questo è vero, problemi cominciano da 4.1 e superiori. – Yosi199

risposta

12

Secondo il codice, nessuno di questi metodi sono mai chiamati, perché non si utilizza mai il TimePickerDialogs.

Detto questo, c'è un problema noto relativo al comportamento di DatePickerDialog/TimePickerDialog che possono essere rilevanti: http://code.google.com/p/android/issues/detail?id=34833

+0

Grazie per la rapida risposta Mark, ho aggiunto il codice che chiama l'intero flusso. Con il clic del pulsante chiami setDate() e il flusso inizia. – Yosi199

+0

@ Yosi199: se il bug che ho citato non ti aiuta, non ho altre risposte. Tuttavia, mi sembra che sarebbe meglio per l'utente avere un singolo 'DateAndTimeActivity', che ospita un' DatePicker' e un 'TimePicker', piuttosto che agitarsi con due finestre di dialogo separate. – CommonsWare

+0

Ho in programma di riesaminare l'errore perché c'è una soluzione temporanea suggerita nel link che hai fornito. Altrimenti rivedrò il mio codice e prenderò in considerazione il tuo suggerimento. Ti ringrazio molto per il tuo tempo e mi hai aiutato. – Yosi199

0

ho provato ed è il lavoro bene con me se avete ancora il problema provare a utilizzare il classic singleton

Qualcosa di simile :) Per saperne di più su di esso.

public void setStartTime() { 

    TimePickerDialog setStartTimeDialog = NULL; 
    if(setStartTimeDialog == null) { 
     new TimePickerDialog(Shifts.this, startTimePicker, dateAndTime.get(Calendar.HOUR),dateAndTime.get(Calendar.MINUTE), true); 

    setStartTimeDialog.setTitle("Started At:"); 
     } 
    setStartTimeDialog.show(); 

} 
+0

Grazie per il vostro aiuto ma questo non mi ha aiutato. Ho aggiornato il codice, quindi apprezzerò se riesci a dargli un'altra occhiata. Grazie – Yosi199

2

Se si guarda allo source Android sembra che onTimeSet() viene chiamato durante onStop() . La finestra di dialogo chiama anche onTimeSet() nel suo metodo onClick().

Per ovviare a questo ho dovuto ignorare le finestre di dialogo respingere e annullare le funzioni per impostare un valore booleano che ho controllato se l'onTimeSet era stato chiamato dal bottone clic o respingere/annullare

+0

grazie, questo non è più pertinente, ma ho ancora apprezzano queste informazioni per un utilizzo futuro – Yosi199

3

Ecco una soluzione di base, per qualcuno che ha bisogno di un TimeChooserDialog, che non chiama l'ascoltatore per due volte, con le opzioni di base

public static AlertDialog getTimePickerDialog(Context context, final OnTimeSetListener listener, int hour, int minute, boolean is24HFormat) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(context); 
    final TimePicker timePicker = new TimePicker(context); 
    timePicker.setIs24HourView(is24HFormat); 
    timePicker.setCurrentHour(hour); 
    timePicker.setCurrentMinute(minute); 
    builder.setView(timePicker); 
    builder.setPositiveButton(android.R.string.ok, new OnClickListener() { 
     @Override 
     public void onClick(DialogInterface arg0, int arg1) { 
      if(null != listener) { 
       listener.onTimeSet(timePicker, timePicker.getCurrentHour(), timePicker.getCurrentMinute()); 
      } 
     } 
    }); 
    builder.setNegativeButton(android.R.string.cancel, null); 
    return builder.create(); 
} 
+0

Questa chiamata la finestra di dialogo personalizzata che hai fatto due volte. – James

-1

ho affrontato questo problema mostrando il TimePicker due volte. Ho superato il onStop() di TimePickerDialog e questo ha risolto il problema. Inoltre non dovresti chiamare super.onStop() nel tuo overriden onStop().

@Override 
public void onStop() { 
    //super.onStop(); 
    Log.d(TAG, "onStop of starttime TimePickerDialog."); 
} 
+0

03-14 15: 18: 47.891: E/AndroidRuntime (29055): android.app.SuperNotCalledException: Fragment DatePickerFragment {425cf2a0} non ha effettuato la chiamata a super.onStop() 03-14 15: 18: 47.891: E/AndroidRuntime (29055): \t su android.app.Fragment.performStop (Fragment.java:1961) 03-14 15: 18: 47.891: E/AndroidRuntime (29055): \t su android.app.FragmentManagerImpl.moveToState (FragmentManager. java: 970) –

0

Non utilizzare TimePickerDialog o DatePickerDialog incorporati. Invece crea una finestra di dialogo personalizzata come quello mostrato qui. È semplice e facile da usare e funziona!

 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     final TimePicker timePicker = new TimePicker(getActivity()); 
     builder.setTitle("Set Time"); 
     builder.setView(timePicker); 
     builder.setNegativeButton("Cancel", new OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.setPositiveButton("OK"), new OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       int minute = timePicker.getCurrentMinute(); 
       int hourOfDay = timePicker.getCurrentHour(); 
      } 
     }); 
     builder.show(); 
1

Lo stesso problema si verifica con me per TimePicker. Risolvo quel problema.

new TimePickerDialog.OnTimeSetListener() { 
    @Override 
    public void onTimeSet(TimePicker view, int setHour, int setMinute) { 
     if (view.isShown()) { 
      // This method will return true only once 
     } 
    } 
}; 

iShown():

Restituisce la visibilità di questo punto di vista e tutti i suoi antenati

Restituisce True se questo punto di vista e tutti i suoi antenati sono visibili

0

Invece di violare super.onClose() o facendo finestre di dialogo personalizzate, lo risolvo avvolgendo listener reale e estendendo TimePickerDialog che abilita e disabilita l'inoltro da wrapper a listener reale. Non è un calo nella sostituzione, ma è abbastanza pulito.

public class TimePickerDialogCustom extends TimePickerDialog 
{ 
    protected TimePickerDialogOnTimeSetListenerWrapper listenerWrapper; 

    public TimePickerDialogCustom(Context context, 
      TimePickerDialogOnTimeSetListenerWrapper listener, 
      int hourOfDay, int minute, boolean is24HourView) 
    { 
     super(context, listener, hourOfDay, minute, is24HourView); 
     listenerWrapper = listener; 
    } 
    @Override 
    protected void onStop() 
    { 
     if (listenerWrapper != null) 
      listenerWrapper.enabled = false; 
     super.onStop(); 
     if (listenerWrapper != null) 
      listenerWrapper.enabled = true; 
    } 
    public static final class TimePickerDialogOnTimeSetListenerWrapper implements TimePickerDialog.OnTimeSetListener 
    { 
     private boolean enabled = true; 
     private final TimePickerDialog.OnTimeSetListener delegate; 

     public TimePickerDialogOnTimeSetListenerWrapper(TimePickerDialog.OnTimeSetListener delegate) 
     { 
      this.delegate = delegate; 
     } 
     @Override 
     public void onTimeSet(TimePicker view, int hourOfDay, int minute) 
     { 
      if (enabled) 
      { 
       this.delegate.onTimeSet(view, hourOfDay, minute); 
      } 
     } 
    } 
} 

Poi, per usarlo:

TimePickerDialogCustom.TimePickerDialogOnTimeSetListenerWrapper listenerWrapper = 
      new TimePickerDialogCustom.TimePickerDialogOnTimeSetListenerWrapper(realListener); 
    // Create a new instance of DatePickerDialog and return it 
    TimePickerDialogCustom dialog = new TimePickerDialogCustom(
      getActivity(), 
      listenerWrapper, 
      hourOfDay, 
      minute, 
      DateFormat.is24HourFormat(getActivity())); 
Problemi correlati