按下后退按钮关闭DatePickerDialog

在我看来,我有一个按钮,当按下时会popup一个DatePickerDialog。 poppedup对话框有一个“完成”按钮。 当我按下该按钮时,所选日期将填充到EditText框中。

现在,当我按下后退按钮( 返回键 ),它仍然在EditText中填充日期。 如何在不从中返回任何值的情况下关闭对话框。

这是我得到的代码 –

调用片段的活动:

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

Dialog的片段(基于Android 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); } } 

似乎没有与onDataSet类似的方法来处理未设置数据的情况。

有没有办法取消/解除popup的datepicker而没有得到它的价值?

谢谢。

看起来Jelybean存在一个错误,其中“取消”按钮不起作用(因此后退按钮)。 这是在Jelly Bean中讨论的DatePickerDialog —有没有办法取消?

David Cesarino在上面的post中报告了这个错误和解决方法,在这里公布了他的解决方案。

cavega稍微修改了上述解决方案,以允许将DatePickerDialog中的日期初始化为今天的日期以外的其他日期。 代码可以在这里find。 我使用他的解决方案并让它工作。

我写了标准的DatePickerDialog的简单inheritance者,对我来说很好用:

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

使用对话框示例(免费奖励:在对话框中添加“取消”按钮以获得更好的可用性):

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

我也在努力解决这个问题,但解决方案非常简单。 DialogFragment实现DialogInterface.OnCancelListener和DialogInterface.OnDismissListener,因为在DialogInterface.OnDismissListener.onDismiss之前调用DialogInterface.OnCancelListener.onCancel,您可以清除onCancel中的日期值,并仅在日期值为on时才调用onDismiss中的TransactionActivity.populateSetDate方法不是0。

另外:为了使Fragment更加独立,最好将Fragment定义为调用活动必须实现的公共接口,这样就可以在接口而不是活动上调用populateSetDate方法。

请参阅下面的代码以实现onCancel和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); } } } 
 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; } } 

上面的代码对我有用。 该对话框设置并取消按钮。 设置将设置日期,取消将关闭对话框。 根据您的需要进行修改。 单击后退按钮也将关闭对话框。

我想你是在问这个问题

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

您可以尝试在alertDialog中包含此内容

如果取消该对话框,mEdit将返回为空。 mEdit.setText("");

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

使用以下方法,当用户按下“ 返回”按钮时调用该方法。 此方法属于Activity

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

您可以为正按钮实现自定义OnClickListener,而不是实现自定义DatePickerDialog:

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

任何后退或点击空白区域都会忽略对话框,什么都不做。