2015-10-15 21 views
5

Ho 4 timePicker nella mia app. La finestra di dialogo timePicker si aprirà quando l'utente fa doppio clic sullo editText. Ma a volte quando accidentalmente clicco più di due volte, l'app si è bloccata e ha detto che il frammento è già stato aggiunto. Come posso risolvere questo? Dopo aver fatto clic su editText due volte, voglio che la finestra di dialogo timePicker sia visualizzata con un solo clic sullo editText.Come aggiungere timePicker usando il frammento?

public void onClick(View v) { 
     int id = v.getId(); 
     if (id == R.id.editTextTI1) { 
      tp.setFlag(TimePick.FLAG_START_DATE); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTO1) { 
      tp.setFlag(TimePick.FLAG_END_DATE); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTI2) { 
      tp.setFlag(TimePick.FLAG_START_DATE1); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTO2) { 
      tp.setFlag(TimePick.FLAG_END_DATE1); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTI3) { 
      tp.setFlag(TimePick.FLAG_START_DATE2); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTO3) { 
      tp.setFlag(TimePick.FLAG_END_DATE2); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTI4) { 
      tp.setFlag(TimePick.FLAG_START_DATE3); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 
     if (id == R.id.editTextTO4) { 
      tp.setFlag(TimePick.FLAG_END_DATE3); 
      FragmentTransaction ft = getFragmentManager().beginTransaction(); 
      tp.show(ft, "TimePicker"); 
     } 

    } 




    public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener { 

     public static final int FLAG_START_DATE = 00; 
     public static final int FLAG_END_DATE = 01; 
     public static final int FLAG_START_DATE1 = 10; 
     public static final int FLAG_END_DATE1 = 11; 
     public static final int FLAG_START_DATE2 = 20; 
     public static final int FLAG_END_DATE2 = 21; 
     public static final int FLAG_START_DATE3 = 30; 
     public static final int FLAG_END_DATE3 = 31; 
     private int flag = 00; 

     @Override 
     public Dialog onCreateDialog(Bundle savedInstanceState) { 

      final Calendar c = Calendar.getInstance(); 
      int hour = c.get(Calendar.HOUR_OF_DAY); 
      int minute = c.get(Calendar.MINUTE); 

      return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity())); 
     } 

     public void setFlag(int i) { 
      flag = i; 
     } 

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

      if (flag == FLAG_START_DATE) { 
       start.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       b = start.getText().toString(); 
      } 
      if (flag == FLAG_END_DATE) { 
       end.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       c = end.getText().toString(); 
      } 
      if (flag == FLAG_START_DATE1) { 
       start1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       d = start1.getText().toString(); 
      } 
      if (flag == FLAG_END_DATE1) { 
       end1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       e1 = end1.getText().toString(); 
      } 
      if (flag == FLAG_START_DATE2) { 
       start2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       f = start2.getText().toString(); 
      } 
      if (flag == FLAG_END_DATE2) { 
       end2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       g = end2.getText().toString(); 
      } 
      if (flag == FLAG_START_DATE3) { 
       start3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       h = start3.getText().toString(); 
      } 
      if (flag == FLAG_END_DATE3) { 
       end3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
       i = end3.getText().toString(); 
      } 

LogCat errore

10-15 12:53:17.113 7943-7943/com.example.project.project E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: com.example.project.project, PID: 7943 
    java.lang.IllegalStateException: Fragment already added: TimePick{7c7eb96 #0 TimePicker} 
      at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1219) 
      at android.app.BackStackRecord.run(BackStackRecord.java:715) 
      at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535) 
      at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:148) 

risposta

2

Il codice è così hardcoded e non facile da estendere, il che potrebbe portare a molti bug in futuro. Si dovrebbe incapsulare la logica generale, come massimo, come si può, quindi in caso di corrente:

public void onClick(View v) { 
    EditText editText = (EditText) v; 
    if (tp==null || !tp.isAdded()){ 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     tp = new TimePick(editText); 
     tp.show(ft, "TimePicker"); 
    } 
} 

@Override 
public void onStop() { 
    super.onStop(); 
    if (tp.isAdded()) tp.dismiss(); 
} 

public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener { 

    private EditText editText; 

    public TimePick(EditText editText) { 
     this.editText = editText; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

     final Calendar c = Calendar.getInstance(); 
     int hour = c.get(Calendar.HOUR_OF_DAY); 
     int minute = c.get(Calendar.MINUTE); 

     return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity())); 
    } 

    @Override 
    public void onTimeSet(TimePicker view, int hourofDay, int minute) { 
     editText.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute)); 
    } 
} 

questo codice non cercherà di creare nuovi picker tempo se c'è ne è sullo schermo. È possibile passare a edittext di destinazione in un frammento timePicker. Quando hai bisogno di valori da questi edittexts (le tue variabili a, b, c, d ...) puoi leggerlo quando necessario, non in onTimeSetMethod.

Il metodo onStop è stato fornito per gestire i casi di ricreazione attività. Qui ho solo nascosto Timepicker attivo.

+0

Ciao Beloo, grazie per aver dedicato del tempo per risolvere il mio problema. Come posso passare altre variabili al frammento timePicker? – John

+0

Si potrebbe farlo tramite contstructor, setter. Assicurati di averne davvero bisogno. Se hai descritto per che cosa hai bisogno di loro posso essere più dettagliato – Beloo

+0

puoi vedere l'immagine sul lato destro http://i.stack.imgur.com/45hI5.png – John

1

Si sta aggiungendo la stessa istanza DialogFragment due volte, per risolvere questo problema, verificare se TimePicker viene aggiunto con getFragmentManager.findFragmentByTag("TimePicker").

+0

Dove posso controllare? – John

+0

Ogni volta che chiamate 'tp.show (ft," TimePicker ")', viene aggiunto il 'DialogFragment', quindi l'eccezione. Controllalo prima della chiamata o puoi usare una nuova istanza ogni volta poiché 'DialogFragment' viene rimosso quando si chiude. – Neil

+0

IMO è opportuno utilizzare la nuova istanza di dialogo, non è necessario implementare molto codice di codice per reimpostare lo stato e la struttura dati e, come una considerazione, la finestra di dialogo leggera ha un impatto minimo su allocazione della memoria. – Neil