按下后退按钮取消DatePickerDialog

时间:2013-03-08 07:12:05

标签: android android-fragments

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

现在,当我按下后退按钮(Back button)时,它仍会在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指南中的this页面):

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的方法来处理未设置数据时的情况。

有没有办法取消/取消弹出的日期选择器而不会获得它的值?

感谢。

8 个答案:

答案 0 :(得分:6)

看起来Jelybean存在一个错误,其中“取消”按钮不起作用(因此后退按钮)。这在Jelly Bean DatePickerDialog --- is there a way to cancel?

中讨论

David Cesarino,在上述帖子中报告了错误和解决方法,发布了他的解决方案hereSO

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

我也在努力解决这个问题,但解决方案非常简单。 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);
    }
  }
}

答案 3 :(得分: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;
        }
 }

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

答案 4 :(得分:0)

我想你要求这个

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

答案 5 :(得分:0)

您可以尝试在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();                           

            }
});

答案 6 :(得分:0)

使用以下方法,当用户按返回按钮时调用该方法。此方法为Activity

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

    dialog.dismiss();
}

答案 7 :(得分:0)

您可以为正向按钮实现自定义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()));
        }
}

任何后退或点击空白区域都会在没有任何操作的情况下解除对话框。