• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.app;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.StyleRes;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.DialogInterface.OnClickListener;
25 import android.os.Bundle;
26 import android.util.TypedValue;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.widget.Button;
30 import android.widget.DatePicker;
31 import android.widget.DatePicker.OnDateChangedListener;
32 import android.widget.DatePicker.ValidationCallback;
33 
34 import com.android.internal.R;
35 
36 import java.util.Calendar;
37 
38 /**
39  * A simple dialog containing an {@link android.widget.DatePicker}.
40  * <p>
41  * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
42  * guide.
43  */
44 public class DatePickerDialog extends AlertDialog implements OnClickListener,
45         OnDateChangedListener {
46     private static final String YEAR = "year";
47     private static final String MONTH = "month";
48     private static final String DAY = "day";
49 
50     private final DatePicker mDatePicker;
51 
52     private OnDateSetListener mDateSetListener;
53 
54     /**
55      * 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
59      */
DatePickerDialog(@onNull Context context)60     public DatePickerDialog(@NonNull Context context) {
61         this(context, 0, null, Calendar.getInstance(), -1, -1, -1);
62     }
63 
64     /**
65      * 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
71      */
DatePickerDialog(@onNull Context context, @StyleRes int themeResId)72     public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId) {
73         this(context, themeResId, null, Calendar.getInstance(), -1, -1, -1);
74     }
75 
76     /**
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      */
DatePickerDialog(@onNull Context context, @Nullable OnDateSetListener listener, int year, int month, int dayOfMonth)88     public DatePickerDialog(@NonNull Context context, @Nullable OnDateSetListener listener,
89             int year, int month, int dayOfMonth) {
90         this(context, 0, listener, null, year, month, dayOfMonth);
91     }
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
102      * @param monthOfYear the initially selected month of the year (0-11 for
103      *                    compatibility with {@link Calendar#MONTH})
104      * @param dayOfMonth the initially selected day of month (1-31, depending
105      *                   on month)
106      */
DatePickerDialog(@onNull Context context, @StyleRes int themeResId, @Nullable OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth)107     public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,
108             @Nullable OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth) {
109         this(context, themeResId, listener, null, year, monthOfYear, dayOfMonth);
110     }
111 
DatePickerDialog(@onNull Context context, @StyleRes int themeResId, @Nullable OnDateSetListener listener, @Nullable Calendar calendar, int year, int monthOfYear, int dayOfMonth)112     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 
136         mDateSetListener = listener;
137     }
138 
resolveDialogTheme(@onNull Context context, @StyleRes int themeResId)139     static @StyleRes int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) {
140         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 
149     @Override
onDateChanged(@onNull DatePicker view, int year, int month, int dayOfMonth)150     public void onDateChanged(@NonNull DatePicker view, int year, int month, int dayOfMonth) {
151         mDatePicker.init(year, month, dayOfMonth, this);
152     }
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      */
setOnDateSetListener(@ullable OnDateSetListener listener)159     public void setOnDateSetListener(@Nullable OnDateSetListener listener) {
160         mDateSetListener = listener;
161     }
162 
163     @Override
onClick(@onNull DialogInterface dialog, int which)164     public void onClick(@NonNull DialogInterface dialog, int which) {
165         switch (which) {
166             case BUTTON_POSITIVE:
167                 if (mDateSetListener != null) {
168                     // Clearing focus forces the dialog to commit any pending
169                     // changes, e.g. typed text in a NumberPicker.
170                     mDatePicker.clearFocus();
171                     mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(),
172                             mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
173                 }
174                 break;
175             case BUTTON_NEGATIVE:
176                 cancel();
177                 break;
178         }
179     }
180 
181     /**
182      * Returns the {@link DatePicker} contained in this dialog.
183      *
184      * @return the date picker
185      */
186     @NonNull
getDatePicker()187     public DatePicker getDatePicker() {
188         return mDatePicker;
189     }
190 
191     /**
192      * Sets the current date.
193      *
194      * @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)
198      */
updateDate(int year, int month, int dayOfMonth)199     public void updateDate(int year, int month, int dayOfMonth) {
200         mDatePicker.updateDate(year, month, dayOfMonth);
201     }
202 
203     @Override
onSaveInstanceState()204     public Bundle onSaveInstanceState() {
205         final Bundle state = super.onSaveInstanceState();
206         state.putInt(YEAR, mDatePicker.getYear());
207         state.putInt(MONTH, mDatePicker.getMonth());
208         state.putInt(DAY, mDatePicker.getDayOfMonth());
209         return state;
210     }
211 
212     @Override
onRestoreInstanceState(Bundle savedInstanceState)213     public void onRestoreInstanceState(Bundle savedInstanceState) {
214         super.onRestoreInstanceState(savedInstanceState);
215         final int year = savedInstanceState.getInt(YEAR);
216         final int month = savedInstanceState.getInt(MONTH);
217         final int day = savedInstanceState.getInt(DAY);
218         mDatePicker.init(year, month, day, this);
219     }
220 
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     };
230 
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          */
onDateSet(DatePicker view, int year, int month, int dayOfMonth)243         void onDateSet(DatePicker view, int year, int month, int dayOfMonth);
244     }
245 }
246