2013-03-08 17 views
5

Na moim widoku mam przycisk, który po naciśnięciu wyskakuje DatePickerDialog. W oknie podręcznym pojawi się przycisk "Gotowe". Po naciśnięciu tego przycisku wybrana data zostanie umieszczona w polu EditText.Odrzuć DatePickerDialog po naciśnięciu przycisku cofania

Teraz, po naciśnięciu przycisku Wstecz (Back button), nadal wypełnia datę w EditText. Jak zamknąć okno bez zwracania z niego wartości.

Jest to kod mam got-

Aktywność który powołuje się na 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); 
    } 
} 

Fragment dla okna (na podstawie this stronę na Android przewodników API):

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

    } 
} 

Nie istnieje metoda analogiczna do onDataSet do obsługi przypadku, gdy dane nie zostały ustawione.

Czy istnieje sposób, aby anulować/odrzucić wyskakujący datepicker bez pobierania jego wartości?

Dzięki.

Odpowiedz

6

Wygląda na to, że jest to błąd z Jelybean gdzie Anuluj przycisk nie działa (& stąd przycisk back). Jest to omówione w Jelly Bean DatePickerDialog --- is there a way to cancel?

David Cesarino, który zgłosił błąd i obejście w powyższym poście, pisał swoje rozwiązanie here i SO.

cavega nieznacznie zmodyfikował powyższe rozwiązanie, aby umożliwić inicjalizację daty w DatePickerDialog na coś innego niż dzisiejsza data. Kod można znaleźć here. Użyłem jego rozwiązania i zmusiłem go do działania.

0

myślę, że proszą o tym

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

To nie wydają się działać. To, co starałem: \t 'dialog.setOnKeyListener (nowa Dialog.OnKeyListener() { \t \t @Override \t \t public boolean onkey (DialogInterface arg0, int keyCode, wydarzenie keyEvent) { \t \t \t if (kEYCODE == KeyEvent.KEYCODE_BACK) { \t \t \t \t dialog.dismiss(); } zwraca fałsz; \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; 
     } 
} 

Powyższy kod pracował dla mnie. Okno dialogowe ustawiło i anulowało przycisk. Set ustawi datę, a cancel spowoduje zamknięcie okna dialogowego. Zmień to samo w zależności od potrzeb. Kliknięcie przycisku Wstecz spowoduje również zamknięcie okna dialogowego.

+0

Używam fragmentów w moim podejściu i myślę, że jeśli mam rację, to jest sposób, aby przejść do ICS i powyżej .. – Bharat

+0

Chcesz powiedzieć, że powyższe nie działa w Fragments ??. Powyższe powinno działać we fragmentach. Nie próbowałem. Ale powinno działać. Nie widzę powodu, dla którego to nie zadziała n fragmentów. Ktoś inny może z tym zrobić. – Raghunandan

0

Można spróbować uwzględnienie tego w swojej alertDialog

Jeśli anulować okno, medit powróci jako pusty. 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 wydaje się nie mieć tej metody w trybie Anuluj. Oto, co mam: 'ostatnie okno dialogowe DatePickerDialog = new DatePickerDialog (getActivity(), this, yy, mm, dd); \t \t dialog.setOnCancelListener (nowa OnCancelListener() {...} '' mogę nie dotyczy wiadomości arguments' na Eclipse. – Bharat

+0

mój zły. I mylone, że z tym. –

0

zastosowanie następująca metoda, która jest wywoływana, gdy użytkownik naciśnie przycisk Powrót. Ta metoda ma numer Activity.

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

    dialog.dismiss(); 
} 
+0

Mam ten DatePickerDialog we fragmencie Klasa publiczna SelectDateFragment rozszerza DialogFragment. Wydaje się, że onBackPressed() nie ma metody w protokole dla DialogFragment..Eclipse mówi: "Metoda onBackPressed() typu SelectDateFragment musi przesłonić lub zaimplementować metodę nadtypu" – Bharat

+0

Ale istnieje metoda w 'FragmentActivity' .Nie sądzisz, że możesz zrobić słuchacza w' DialogFragment' i kiedy aktywność dostaje ** Wstecz ** przycisk wciśnięty wydarzenie, wystrzeliwujesz słuchacza ?? –

3

Napisałem prosty następca standardowej DatePickerDialog że działa dobrze dla mnie:

/** 
* 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(); 
    } 
} 

Korzystanie przykład dialogowe (bonus: dodawanie przycisk Anuluj, aby dialog na jeszcze lepszą użyteczność):

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

Zamiast implementacji niestandardowego narzędzia DatePickerDialog można zaimplementować niestandardowy program OnClickListener dla przycisku dodatniego:

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

Dowolne cofnięcie lub dotknięcie pustego obszaru spowoduje zamknięcie okna dialogowego z robieniem nic.

2

Walczyłem z tym również, ale rozwiązanie jest bardzo proste. DialogFragment implementuje DialogInterface.OnCancelListener i DialogInterface.OnDismissListener, a ponieważ DialogInterface.OnCancelListener.onCancel zostaje wywołana przed DialogInterface.OnDismissListener.onDismiss, możesz wyczyścić wartości dat na onAnuluj i wywołaj metodę TransactionActivity.populateSetDate w onDismiss tylko, jeśli wartości daty są nie 0.

tak na marginesie: do fragmentu więcej samodzielnie, jest to dobra praktyka, że ​​fragment definiuje interfejs publiczny że aktywność wywołujący musi implementować, więc można wywołać metodę populateSetDate na interfejsie zamiast aktywności.

Zobacz kod poniżej dla realizacji onCancel i 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); 
    } 
    } 
} 
Powiązane problemy