2013-03-08 5 views
5

Sur ma vue, j'ai un bouton qui, lorsqu'il est pressé ouvre un DatePickerDialog. La boîte de dialogue pop upup a un bouton "Terminé". Lorsque j'appuie sur ce bouton, la date sélectionnée est renseignée dans une zone EditText. Maintenant, lorsque j'appuie sur le bouton Précédent (Back button), il remplit toujours la date dans l'EditText. Comment est-ce que je rejette la boîte de dialogue sans retourner de valeur?Quitter DatePickerDialog en appuyant sur le bouton Précédent

C'est le code que j'ai got-

L'activité qui invoque le fragment:

public class TransactionActivity extends FragmentActivity implements iRibbonMenuCallback {   
    ..... 
    public void selectDate(View view) { 
     // This is the method invoked by the button 
     SelectDateFragment newFragment = new SelectDateFragment(); 
     newFragment.show(getSupportFragmentManager(), "DatePicker"); 
    } 

    public void populateSetDate(int year, int month, int day) { 
     // Puts the date in the EditText box 
     mEdit = (EditText)findViewById(R.id.DateText); 
     mEdit.setText(month+"/"+day+"/"+year); 
    } 
} 

Un fragment de la boîte de dialogue (basé sur this page sur les guides de l'API Android):

public class SelectDateFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { 
    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     final Calendar calendar = Calendar.getInstance(); 
     int yy = calendar.get(Calendar.YEAR); 
     int mm = calendar.get(Calendar.MONTH); 
     int dd = calendar.get(Calendar.DAY_OF_MONTH); 
     return new DatePickerDialog(getActivity(), this, yy, mm, dd); 
    } 

    public void onDateSet(DatePicker view, int yy, int mm, int dd) { 
      // Calls a method on the activity which invokes this fragment 
     ((TransactionActivity)getActivity()).populateSetDate(yy, mm+1, dd);  

    } 
} 

Il ne semble pas exister de méthode analogue à onDataSet pour gérer le cas lorsque les données n'ont pas été définies.

Existe-t-il un moyen d'annuler/de rejeter le datpicker surgi sans obtenir sa valeur?

Merci.

Répondre

6

On dirait qu'il ya un bug avec Jelybean où le bouton Annuler ne fonctionne pas (& donc le bouton de retour). Ceci est discuté dans Jelly Bean DatePickerDialog --- is there a way to cancel?

David Cesarino, qui a signalé le bogue et solution de contournement dans le message ci-dessus, a affiché sa solution here et SO.

cavega légèrement modifié la solution ci-dessus pour permettre l'initialisation de la date dans le DatePickerDialog à quelque chose d'autre que la date d'aujourd'hui. Le code peut être trouvé here. J'ai utilisé sa solution et l'ai fait fonctionner.

0

Je pense que vous demandez ce

setOnCancelListener(new OnCancelListener() { 
       @Override 
       public void onCancel(DialogInterface dialog) { 
    } 
+0

Cela ne semble pas fonctionner. Voilà ce que j'ai essayé: \t 'dialog.setOnKeyListener (nouvelle Dialog.OnKeyListener() { \t \t @Override \t \t OnKey public boolean (DialogInterface arg0, int codeTouche, événement KeyEvent) { \t \t \t if (codeTouche == KeyEvent.KEYCODE_BACK) { \t \t \t \t dialog.dismiss();} return false; \t} }); – Bharat

1
public class pickerdate extends Activity { 
/** Called when the activity is first created. */ 
    private TextView mDateDisplay; 
    private Button mPickDate; 
    private int mYear; 
    private int mMonth; 
    private int mDay; 

    static final int DATE_DIALOG_ID = 0; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 


     mDateDisplay = (TextView) findViewById(R.id.dateDisplay); 
     mPickDate = (Button) findViewById(R.id.pickDate); 


     mPickDate.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       showDialog(DATE_DIALOG_ID); 
      } 
     }); 


     final Calendar c = Calendar.getInstance(); 
     mYear = c.get(Calendar.YEAR); 
     mMonth = c.get(Calendar.MONTH); 
     mDay = c.get(Calendar.DAY_OF_MONTH); 

     updateDisplay(); 
    } 
    private void updateDisplay() { 
     mDateDisplay.setText(
      new StringBuilder() 
        // Month is 0 based so add 1 
        .append(mMonth + 1).append("-") 
        .append(mDay).append("-") 
        .append(mYear).append(" ")); 
    } 
    private DatePickerDialog.OnDateSetListener mDateSetListener = 
     new DatePickerDialog.OnDateSetListener() { 

      public void onDateSet(DatePicker view, int year, 
            int monthOfYear, int dayOfMonth) { 
       mYear = year; 
       mMonth = monthOfYear; 
       mDay = dayOfMonth; 
       updateDisplay(); 
      } 
     }; 
     @Override 
     protected Dialog onCreateDialog(int id) { 
      switch (id) { 
      case DATE_DIALOG_ID: 
       return new DatePickerDialog(this, 
          mDateSetListener, 
          mYear, mMonth, mDay); 
      } 
      return null; 
     } 
} 

Le code ci-dessus a fonctionné pour moi. Le dialogue a réglé et annuler le bouton. L'ensemble réglera la date et annulera la boîte de dialogue. Modifiez la même chose selon vos besoins. Cliquer sur le bouton de retour permet également de fermer la boîte de dialogue.

+0

J'utilise des fragments dans mon approche et je pense, si j'ai raison, c'est la voie à suivre pour ICS et au-dessus .. – Bharat

+0

Vous voulez dire que ce qui précède ne fonctionne pas dans Fragments ??. Ce qui précède devrait fonctionner en fragments. Je n'ai pas essayé. Mais ça devrait marcher. Je ne vois aucune raison pour que cela ne fonctionne pas n fragments. Quelqu'un d'autre peut vous avec cela. – Raghunandan

0

Vous pouvez essayer inclure dans votre AlertDialog

Si vous annulez la boîte de dialogue, Medit retournera aussi vide. mEdit.setText("");

AlertDialog alertDialog; 

    alertDialog.setOnCancelListener(new OnCancelListener() 
    {     
      @Override 
      public void onCancel(DialogInterface dialog) 
      { 
       // TODO Auto-generated method stub 
        mEdit.setText(""); 
        dialog.dismiss();       

      } 
}); 
+0

DatePickerDialog ne semble pas avoir la méthode onCancel. Voici ce que j'ai: 'final DatePickerDialog dialog = nouveau DatePickerDialog (getActivity(), this, yy, mm, dd); \t \t dialog.setOnCancelListener (nouvelle OnCancelListener() {...} '' Je reçois pas applicable pour le message arguments' sur Eclipse. – Bharat

+0

mon mal. Je me trompe que ce. –

0

utilisation de la méthode suivante, qui est appelée lorsque l'utilisateur appuie sur le bouton Retour . Cette méthode est de Activity.

@Override 
public void onBackPressed() { 
    // TODO Auto-generated method stub 
    super.onBackPressed(); 

    dialog.dismiss(); 
} 
+0

J'ai la DatePickerDialog dans un fragment La classe onBackPressed() ne semble pas avoir de méthode dans le protocole pour DialogFragment ..Eclipse dit 'La méthode onBackPressed() de type SelectDateFragment doit remplacer ou implémenter une méthode supertype' – Bharat

+0

il y a une méthode dans 'FragmentActivity'. Ne pensez-vous pas que vous pouvez faire un écouteur dans' DialogFragment' et quand l'activité obtient l'événement pressé ** Back ** button, vous déclenchez un écouteur ?? –

3

j'ai écrit successeur simple norme DatePickerDialog qui fonctionne bien pour moi:

/** 
* Enhanced date picker dialog. Main difference from ancestor is that it calls 
* OnDateSetListener only when when pressing OK button, and skips event when closing with 
* BACK key or by tapping outside a dialog. 
*/ 
public class IBSDatePickerDialog extends DatePickerDialog { 

    public IBSDatePickerDialog(final Context context, final OnDateSetListener callBack, final int year, final int monthOfYear, final int dayOfMonth) { 
     super(context, callBack, year, monthOfYear, dayOfMonth); 
    } 

    public IBSDatePickerDialog(final Context context, final int theme, final OnDateSetListener callBack, final int year, final int monthOfYear, final int dayOfMonth) { 
     super(context, theme, callBack, year, monthOfYear, dayOfMonth); 
    } 

    @Override 
    public void onClick(final DialogInterface dialog, final int which) { 
     // Prevent calling onDateSet handler when clicking to dialog buttons other, then "OK" 
     if (which == DialogInterface.BUTTON_POSITIVE) 
      super.onClick(dialog, which); 
    } 

    @Override 
    protected void onStop() { 
     // prevent calling onDateSet handler when stopping dialog for whatever reason (because this includes 
     // closing by BACK button or by tapping outside dialog, this is exactly what we try to avoid) 

     //super.onStop(); 
    } 
} 

Exemple d'utilisation de dialogue (bonus gratuit: ajouter le bouton Annuler pour dialogue pour la facilité d'utilisation encore mieux):

public static class datePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { 

    @Override 
    public Dialog onCreateDialog(final Bundle savedInstanceState) { 

     Calendar cal = Calendar.getInstance(); 
     IBSDatePickerDialog dlg = new IBSDatePickerDialog(myActivity, this, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); 

     // Add Cancel button into dialog 
     dlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", (OnClickListener) null); 

     return dlg; 
    } 

    @Override 
    public void onDateSet(final DatePicker view, final int year, final int month, final int day) { 
     // TODO: do whatever you want with date selected 
    } 
} 

public void showDatePickerDialog() { 
    final datePickerFragment f = new datePickerFragment(); 
    f.show(getSupportFragmentManager(), "datePicker"); 
} 
0

lieu de l'implémentation de DatePickerDialog personnalisé, vous pouvez implémenter OnClickListener personnalisé pour le bouton positif:

DatePickerDialog dateDialog = new DatePickerDialog(this, null, year, month, day); 
datePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, 
    getResources().getString(R.string.text_done), 
    new OnDoneClickListener(datePickerDialog)); 

// <...> 

private class OnDoneClickListener implements DialogInterface.OnClickListener { 

     private DatePickerDialog mPickerDialog; 

     BirthDatePickerDialog(DatePickerDialog mPickerDialog) { 
      this.mPickerDialog = mPickerDialog; 
     } 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 
      Calendar cal = Calendar.getInstance(); 
      DatePicker picker = mPickerDialog.getDatePicker(); 
      cal.set(Calendar.YEAR, picker.getYear()); 
      cal.set(Calendar.MONTH, picker.getMonth()); 
      cal.set(Calendar.DAY_OF_MONTH, picker.getDayOfMonth()); 
      spinnerDateBirth.setText(dateFormat.format(cal.getTime())); 
     } 
} 

N'importe lequel de retour ou appuyez sur la zone vide va fermer la boîte de dialogue en ne faisant rien.

2

J'ai lutté avec cela aussi, mais la solution est très simple. DialogFragment implémente DialogInterface.OnCancelListener et DialogInterface.OnDismissListener et parce que DialogInterface.OnCancelListener.onCancel est appelé avant DialogInterface.OnDismissListener.onDismiss, vous pouvez effacer les valeurs de date dans onCancel et appeler la méthode TransactionActivity.populateSetDate dans onDismiss uniquement si les valeurs de date sont En aparté: pour rendre le Fragment plus autonome, il est recommandé que le Fragment définisse une interface publique que l'activité appelante doit implémenter, de sorte que vous pouvez appeler la méthode populateSetDate sur l'interface au lieu de l'activité.

Voir votre code ci-dessous pour la mise en œuvre de la onCancel et onDismiss:

public class SelectDateFragment extends DialogFragment 
    implements DatePickerDialog.OnDateSetListener 
{ 

    private int year; 
    private int month; 
    private int day; 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
    final Calendar calendar = Calendar.getInstance(); 
    int yy = calendar.get(Calendar.YEAR); 
    int mm = calendar.get(Calendar.MONTH); 
    int dd = calendar.get(Calendar.DAY_OF_MONTH); 
    return new DatePickerDialog(getActivity(), this, yy, mm, dd); 
    } 

    public void onDateSet(DatePicker view, int yy, int mm, int dd) { 
    // Calls a method on the activity which invokes this fragment 
    // ((TransactionActivity)getActivity()).populateSetDate(yy, mm+1, dd); 
    year = yy; 
    month = mm; 
    day = dd; 
    } 

    // Gets called before onDismiss, so we can erase the selectedDate 
    @Override 
    public void onCancel(DialogInterface dialog) { 
    year = 0; 
    month = 0; 
    day = 0; 
    } 


    @Override 
    public void onDismiss(DialogInterface dialog) { 
    if (year != 0) { 
     ((TransactionActivity)getActivity()).populateSetDate(year, month + 1, day); 
    } 
    } 
} 
Questions connexes