blob: 9d82ffa838ca57b2c7925ddef31bc3e80f4f5738 [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;
Mathew Inwood4fb17d12018-08-14 14:25:44 +010022import android.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.Context;
24import android.content.DialogInterface;
25import android.content.DialogInterface.OnClickListener;
26import android.os.Bundle;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070027import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.view.LayoutInflater;
29import android.view.View;
Alan Viverette518ff0d2014-08-15 14:20:35 -070030import android.widget.Button;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.widget.DatePicker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.widget.DatePicker.OnDateChangedListener;
Alan Viverette518ff0d2014-08-15 14:20:35 -070033import android.widget.DatePicker.ValidationCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
Svetoslav Ganov42c5cb32012-05-02 01:02:20 -070035import com.android.internal.R;
36
37import java.util.Calendar;
38
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039/**
40 * A simple dialog containing an {@link android.widget.DatePicker}.
Alan Viverettead50da52015-12-17 11:41:05 -050041 * <p>
42 * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
43 * guide.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 */
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020045public class DatePickerDialog extends AlertDialog implements OnClickListener,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 OnDateChangedListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 private static final String YEAR = "year";
48 private static final String MONTH = "month";
49 private static final String DAY = "day";
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020050
Mathew Inwood4fb17d12018-08-14 14:25:44 +010051 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 private final DatePicker mDatePicker;
Svetoslav Ganov42c5cb32012-05-02 01:02:20 -070053
Alan Viverettead50da52015-12-17 11:41:05 -050054 private OnDateSetListener mDateSetListener;
55
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 /**
Alan Viverettead50da52015-12-17 11:41:05 -050057 * Creates a new date picker dialog for the current date using the parent
58 * context's default date picker dialog theme.
59 *
60 * @param context the parent context
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050062 public DatePickerDialog(@NonNull Context context) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040063 this(context, 0, null, Calendar.getInstance(), -1, -1, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 }
65
66 /**
Alan Viverettead50da52015-12-17 11:41:05 -050067 * Creates a new date picker dialog for the current date.
68 *
69 * @param context the parent context
70 * @param themeResId the resource ID of the theme against which to inflate
71 * this dialog, or {@code 0} to use the parent
72 * {@code context}'s default alert dialog theme
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050074 public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040075 this(context, themeResId, null, Calendar.getInstance(), -1, -1, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +020077
Alan Viverettead50da52015-12-17 11:41:05 -050078 /**
79 * Creates a new date picker dialog for the specified date using the parent
80 * context's default date picker dialog theme.
81 *
82 * @param context the parent context
83 * @param listener the listener to call when the user sets the date
84 * @param year the initially selected year
85 * @param month the initially selected month (0-11 for compatibility with
86 * {@link Calendar#MONTH})
87 * @param dayOfMonth the initially selected day of month (1-31, depending
88 * on month)
89 */
Alan Viverette8ae4ff72016-01-13 11:13:50 -050090 public DatePickerDialog(@NonNull Context context, @Nullable OnDateSetListener listener,
Alan Viverettead50da52015-12-17 11:41:05 -050091 int year, int month, int dayOfMonth) {
Alan Viverettea9a75f52016-04-01 13:22:10 -040092 this(context, 0, listener, null, year, month, dayOfMonth);
Alan Viverettead50da52015-12-17 11:41:05 -050093 }
94
95 /**
96 * Creates a new date picker dialog for the specified date.
97 *
98 * @param context the parent context
99 * @param themeResId the resource ID of the theme against which to inflate
100 * this dialog, or {@code 0} to use the parent
101 * {@code context}'s default alert dialog theme
102 * @param listener the listener to call when the user sets the date
103 * @param year the initially selected year
Alan Viverettea9a75f52016-04-01 13:22:10 -0400104 * @param monthOfYear the initially selected month of the year (0-11 for
105 * compatibility with {@link Calendar#MONTH})
Alan Viverettead50da52015-12-17 11:41:05 -0500106 * @param dayOfMonth the initially selected day of month (1-31, depending
107 * on month)
108 */
109 public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,
Alan Viverettea9a75f52016-04-01 13:22:10 -0400110 @Nullable OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth) {
111 this(context, themeResId, listener, null, year, monthOfYear, dayOfMonth);
112 }
Alan Viverettead50da52015-12-17 11:41:05 -0500113
Alan Viverettea9a75f52016-04-01 13:22:10 -0400114 private DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,
115 @Nullable OnDateSetListener listener, @Nullable Calendar calendar, int year,
116 int monthOfYear, int dayOfMonth) {
117 super(context, resolveDialogTheme(context, themeResId));
118
119 final Context themeContext = getContext();
120 final LayoutInflater inflater = LayoutInflater.from(themeContext);
121 final View view = inflater.inflate(R.layout.date_picker_dialog, null);
122 setView(view);
123
124 setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this);
125 setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
126 setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
127
128 if (calendar != null) {
129 year = calendar.get(Calendar.YEAR);
130 monthOfYear = calendar.get(Calendar.MONTH);
131 dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
132 }
133
134 mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
135 mDatePicker.init(year, monthOfYear, dayOfMonth, this);
136 mDatePicker.setValidationCallback(mValidationCallback);
137
Alan Viverette4d1ad992016-03-08 18:48:47 -0500138 mDateSetListener = listener;
Alan Viverettead50da52015-12-17 11:41:05 -0500139 }
140
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500141 static @StyleRes int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) {
Alan Viverettead50da52015-12-17 11:41:05 -0500142 if (themeResId == 0) {
143 final TypedValue outValue = new TypedValue();
144 context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true);
145 return outValue.resourceId;
146 } else {
147 return themeResId;
148 }
149 }
150
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700151 @Override
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500152 public void onDateChanged(@NonNull DatePicker view, int year, int month, int dayOfMonth) {
Alan Viverettead50da52015-12-17 11:41:05 -0500153 mDatePicker.init(year, month, dayOfMonth, this);
Alan Viverettead50da52015-12-17 11:41:05 -0500154 }
155
156 /**
157 * Sets the listener to call when the user sets the date.
158 *
159 * @param listener the listener to call when the user sets the date
160 */
161 public void setOnDateSetListener(@Nullable OnDateSetListener listener) {
162 mDateSetListener = listener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +0200164
Alan Viverette518ff0d2014-08-15 14:20:35 -0700165 @Override
Alan Viverette8ae4ff72016-01-13 11:13:50 -0500166 public void onClick(@NonNull DialogInterface dialog, int which) {
Alan Viverette518ff0d2014-08-15 14:20:35 -0700167 switch (which) {
168 case BUTTON_POSITIVE:
169 if (mDateSetListener != null) {
Alan Viveretteb2b98a00e2015-01-13 17:34:17 -0800170 // Clearing focus forces the dialog to commit any pending
171 // changes, e.g. typed text in a NumberPicker.
172 mDatePicker.clearFocus();
Alan Viverette518ff0d2014-08-15 14:20:35 -0700173 mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(),
174 mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
175 }
176 break;
Alan Viverette16a24bc2014-08-28 11:19:59 -0700177 case BUTTON_NEGATIVE:
178 cancel();
179 break;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700180 }
181 }
182
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800183 /**
Alan Viverettead50da52015-12-17 11:41:05 -0500184 * Returns the {@link DatePicker} contained in this dialog.
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800185 *
Alan Viverettead50da52015-12-17 11:41:05 -0500186 * @return the date picker
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800187 */
Alan Viverettead50da52015-12-17 11:41:05 -0500188 @NonNull
Svetoslav Ganove9730bf2010-12-20 21:25:20 -0800189 public DatePicker getDatePicker() {
190 return mDatePicker;
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800191 }
192
193 /**
194 * Sets the current date.
195 *
Alan Viverettead50da52015-12-17 11:41:05 -0500196 * @param year the year
197 * @param month the month (0-11 for compatibility with
198 * {@link Calendar#MONTH})
199 * @param dayOfMonth the day of month (1-31, depending on month)
Svetoslav Ganov28104e12010-12-19 16:03:07 -0800200 */
Alan Viverettead50da52015-12-17 11:41:05 -0500201 public void updateDate(int year, int month, int dayOfMonth) {
202 mDatePicker.updateDate(year, month, dayOfMonth);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 }
204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 @Override
206 public Bundle onSaveInstanceState() {
Alan Viverette518ff0d2014-08-15 14:20:35 -0700207 final Bundle state = super.onSaveInstanceState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 state.putInt(YEAR, mDatePicker.getYear());
209 state.putInt(MONTH, mDatePicker.getMonth());
210 state.putInt(DAY, mDatePicker.getDayOfMonth());
211 return state;
212 }
Christian Mehlmauere8db3a32010-06-25 20:01:03 +0200213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 @Override
215 public void onRestoreInstanceState(Bundle savedInstanceState) {
216 super.onRestoreInstanceState(savedInstanceState);
Alan Viverette518ff0d2014-08-15 14:20:35 -0700217 final int year = savedInstanceState.getInt(YEAR);
218 final int month = savedInstanceState.getInt(MONTH);
219 final int day = savedInstanceState.getInt(DAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 mDatePicker.init(year, month, day, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 }
Alan Viverette518ff0d2014-08-15 14:20:35 -0700222
223 private final ValidationCallback mValidationCallback = new ValidationCallback() {
224 @Override
225 public void onValidationChanged(boolean valid) {
226 final Button positive = getButton(BUTTON_POSITIVE);
227 if (positive != null) {
228 positive.setEnabled(valid);
229 }
230 }
231 };
Alan Viverettead50da52015-12-17 11:41:05 -0500232
233 /**
234 * The listener used to indicate the user has finished selecting a date.
235 */
236 public interface OnDateSetListener {
237 /**
238 * @param view the picker associated with the dialog
239 * @param year the selected year
240 * @param month the selected month (0-11 for compatibility with
241 * {@link Calendar#MONTH})
koprivaf07a4602018-09-20 11:20:27 -0700242 * @param dayOfMonth the selected day of the month (1-31, depending on
Alan Viverettead50da52015-12-17 11:41:05 -0500243 * month)
244 */
245 void onDateSet(DatePicker view, int year, int month, int dayOfMonth);
246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247}