blob: bd55a06c40f585e3d51c0d978eed18e7a1cad110 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Alan Viverettead50da52015-12-17 11:41:05 -050019import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.StyleRes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
23import android.content.DialogInterface;
24import android.content.DialogInterface.OnClickListener;
25import android.os.Bundle;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070026import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.view.LayoutInflater;
28import android.view.View;
Alan Viverette518ff0d2014-08-15 14:20:35 -070029import android.widget.Button;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.widget.DatePicker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.widget.DatePicker.OnDateChangedListener;
Alan Viverette518ff0d2014-08-15 14:20:35 -070032import android.widget.DatePicker.ValidationCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Svetoslav Ganov42c5cb32012-05-02 01:02:20 -070034import com.android.internal.R;
35
36import java.util.Calendar;
37
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038/**
39 * A simple dialog containing an {@link android.widget.DatePicker}.
Alan Viverettead50da52015-12-17 11:41:05 -050040 * <p>
41 * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
42 * guide.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 */
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020044public class DatePickerDialog extends AlertDialog implements OnClickListener,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 OnDateChangedListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 private static final String YEAR = "year";
47 private static final String MONTH = "month";
48 private static final String DAY = "day";
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 private final DatePicker mDatePicker;
Svetoslav Ganov42c5cb32012-05-02 01:02:20 -070051
Alan Viverettead50da52015-12-17 11:41:05 -050052 private OnDateSetListener mDateSetListener;
53
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 /**
Alan Viverettead50da52015-12-17 11:41:05 -050055 * Creates a new date picker dialog for the current date using the parent
56 * context's default date picker dialog theme.
57 *
58 * @param context the parent context
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050060 public DatePickerDialog(@NonNull Context context) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040061 this(context, 0, null, Calendar.getInstance(), -1, -1, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 }
63
64 /**
Alan Viverettead50da52015-12-17 11:41:05 -050065 * Creates a new date picker dialog for the current date.
66 *
67 * @param context the parent context
68 * @param themeResId the resource ID of the theme against which to inflate
69 * this dialog, or {@code 0} to use the parent
70 * {@code context}'s default alert dialog theme
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050072 public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040073 this(context, themeResId, null, Calendar.getInstance(), -1, -1, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020075
Alan Viverettead50da52015-12-17 11:41:05 -050076 /**
77 * Creates a new date picker dialog for the specified date using the parent
78 * context's default date picker dialog theme.
79 *
80 * @param context the parent context
81 * @param listener the listener to call when the user sets the date
82 * @param year the initially selected year
83 * @param month the initially selected month (0-11 for compatibility with
84 * {@link Calendar#MONTH})
85 * @param dayOfMonth the initially selected day of month (1-31, depending
86 * on month)
87 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050088 public DatePickerDialog(@NonNull Context context, @Nullable OnDateSetListener listener,
Alan Viverettead50da52015-12-17 11:41:05 -050089 int year, int month, int dayOfMonth) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040090 this(context, 0, listener, null, year, month, dayOfMonth);
Alan Viverettead50da52015-12-17 11:41:05 -050091 }
92
93 /**
94 * Creates a new date picker dialog for the specified date.
95 *
96 * @param context the parent context
97 * @param themeResId the resource ID of the theme against which to inflate
98 * this dialog, or {@code 0} to use the parent
99 * {@code context}'s default alert dialog theme
100 * @param listener the listener to call when the user sets the date
101 * @param year the initially selected year
Alan Viverettea9a75f52016-04-01 13:22:10 -0400102 * @param monthOfYear the initially selected month of the year (0-11 for
103 * compatibility with {@link Calendar#MONTH})
Alan Viverettead50da52015-12-17 11:41:05 -0500104 * @param dayOfMonth the initially selected day of month (1-31, depending
105 * on month)
106 */
107 public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,
Alan Viverettea9a75f52016-04-01 13:22:10 -0400108 @Nullable OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth) {
109 this(context, themeResId, listener, null, year, monthOfYear, dayOfMonth);
110 }
Alan Viverettead50da52015-12-17 11:41:05 -0500111
Alan Viverettea9a75f52016-04-01 13:22:10 -0400112 private DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,
113 @Nullable OnDateSetListener listener, @Nullable Calendar calendar, int year,
114 int monthOfYear, int dayOfMonth) {
115 super(context, resolveDialogTheme(context, themeResId));
116
117 final Context themeContext = getContext();
118 final LayoutInflater inflater = LayoutInflater.from(themeContext);
119 final View view = inflater.inflate(R.layout.date_picker_dialog, null);
120 setView(view);
121
122 setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this);
123 setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
124 setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
125
126 if (calendar != null) {
127 year = calendar.get(Calendar.YEAR);
128 monthOfYear = calendar.get(Calendar.MONTH);
129 dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
130 }
131
132 mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
133 mDatePicker.init(year, monthOfYear, dayOfMonth, this);
134 mDatePicker.setValidationCallback(mValidationCallback);
135
Alan Viverette4d1ad992016-03-08 18:48:47 -0500136 mDateSetListener = listener;
Alan Viverettead50da52015-12-17 11:41:05 -0500137 }
138
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500139 static @StyleRes int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) {
Alan Viverettead50da52015-12-17 11:41:05 -0500140 if (themeResId == 0) {
141 final TypedValue outValue = new TypedValue();
142 context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true);
143 return outValue.resourceId;
144 } else {
145 return themeResId;
146 }
147 }
148
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700149 @Override
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500150 public void onDateChanged(@NonNull DatePicker view, int year, int month, int dayOfMonth) {
Alan Viverettead50da52015-12-17 11:41:05 -0500151 mDatePicker.init(year, month, dayOfMonth, this);
Alan Viverettead50da52015-12-17 11:41:05 -0500152 }
153
154 /**
155 * Sets the listener to call when the user sets the date.
156 *
157 * @param listener the listener to call when the user sets the date
158 */
159 public void setOnDateSetListener(@Nullable OnDateSetListener listener) {
160 mDateSetListener = listener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +0200162
Alan Viverette518ff0d2014-08-15 14:20:35 -0700163 @Override
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500164 public void onClick(@NonNull DialogInterface dialog, int which) {
Alan Viverette518ff0d2014-08-15 14:20:35 -0700165 switch (which) {
166 case BUTTON_POSITIVE:
167 if (mDateSetListener != null) {
Alan Viveretteb2b98a00e2015-01-13 17:34:17 -0800168 // Clearing focus forces the dialog to commit any pending
169 // changes, e.g. typed text in a NumberPicker.
170 mDatePicker.clearFocus();
Alan Viverette518ff0d2014-08-15 14:20:35 -0700171 mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(),
172 mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
173 }
174 break;
Alan Viverette16a24bc2014-08-28 11:19:59 -0700175 case BUTTON_NEGATIVE:
176 cancel();
177 break;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700178 }
179 }
180
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800181 /**
Alan Viverettead50da52015-12-17 11:41:05 -0500182 * Returns the {@link DatePicker} contained in this dialog.
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800183 *
Alan Viverettead50da52015-12-17 11:41:05 -0500184 * @return the date picker
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800185 */
Alan Viverettead50da52015-12-17 11:41:05 -0500186 @NonNull
Svetoslav Ganove9730bf2010-12-20 21:25:20 -0800187 public DatePicker getDatePicker() {
188 return mDatePicker;
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800189 }
190
191 /**
192 * Sets the current date.
193 *
Alan Viverettead50da52015-12-17 11:41:05 -0500194 * @param year the year
195 * @param month the month (0-11 for compatibility with
196 * {@link Calendar#MONTH})
197 * @param dayOfMonth the day of month (1-31, depending on month)
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800198 */
Alan Viverettead50da52015-12-17 11:41:05 -0500199 public void updateDate(int year, int month, int dayOfMonth) {
200 mDatePicker.updateDate(year, month, dayOfMonth);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 @Override
204 public Bundle onSaveInstanceState() {
Alan Viverette518ff0d2014-08-15 14:20:35 -0700205 final Bundle state = super.onSaveInstanceState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 state.putInt(YEAR, mDatePicker.getYear());
207 state.putInt(MONTH, mDatePicker.getMonth());
208 state.putInt(DAY, mDatePicker.getDayOfMonth());
209 return state;
210 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +0200211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 @Override
213 public void onRestoreInstanceState(Bundle savedInstanceState) {
214 super.onRestoreInstanceState(savedInstanceState);
Alan Viverette518ff0d2014-08-15 14:20:35 -0700215 final int year = savedInstanceState.getInt(YEAR);
216 final int month = savedInstanceState.getInt(MONTH);
217 final int day = savedInstanceState.getInt(DAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 mDatePicker.init(year, month, day, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 }
Alan Viverette518ff0d2014-08-15 14:20:35 -0700220
221 private final ValidationCallback mValidationCallback = new ValidationCallback() {
222 @Override
223 public void onValidationChanged(boolean valid) {
224 final Button positive = getButton(BUTTON_POSITIVE);
225 if (positive != null) {
226 positive.setEnabled(valid);
227 }
228 }
229 };
Alan Viverettead50da52015-12-17 11:41:05 -0500230
231 /**
232 * The listener used to indicate the user has finished selecting a date.
233 */
234 public interface OnDateSetListener {
235 /**
236 * @param view the picker associated with the dialog
237 * @param year the selected year
238 * @param month the selected month (0-11 for compatibility with
239 * {@link Calendar#MONTH})
240 * @param dayOfMonth th selected day of the month (1-31, depending on
241 * month)
242 */
243 void onDateSet(DatePicker view, int year, int month, int dayOfMonth);
244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245}