blob: 6e3dbd8c5e1d2f7ad95148799cee653674bcfac7 [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.widget;
18
Alan Viverette518ff0d2014-08-15 14:20:35 -070019import android.annotation.Nullable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.annotation.Widget;
21import android.content.Context;
Svetoslav Ganovf5926962011-07-12 12:26:20 -070022import android.content.res.Configuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.res.TypedArray;
24import android.os.Parcel;
25import android.os.Parcelable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.util.AttributeSet;
27import android.util.SparseArray;
Svetoslav Ganovd11e6152012-03-20 12:13:02 -070028import android.view.View;
Svetoslav Ganov8a2a8952011-01-27 17:40:13 -080029import android.view.accessibility.AccessibilityEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
Svetoslav Ganovf5926962011-07-12 12:26:20 -070031import com.android.internal.R;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import java.util.Calendar;
Kenny Rootdddda8d2010-11-15 14:38:51 -080034import java.util.Locale;
Svetoslav Ganove9730bf2010-12-20 21:25:20 -080035import java.util.TimeZone;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37/**
Alan Viveretted25eb9f2014-11-24 14:07:24 -080038 * Provides a widget for selecting a date.
39 * <p>
40 * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
41 * set to {@code spinner}, the date can be selected using year, month, and day
42 * spinners or a {@link CalendarView}. The set of spinners and the calendar
43 * view are automatically synchronized. The client can customize whether only
44 * the spinners, or only the calendar view, or both to be displayed.
45 * </p>
46 * <p>
47 * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is
48 * set to {@code calendar}, the month and day can be selected using a
49 * calendar-style view while the year can be selected separately using a list.
50 * </p>
Svetoslav Ganov50f34d12010-12-03 16:05:40 -080051 * <p>
Scott Main4c359b72012-07-24 15:51:27 -070052 * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
53 * guide.
Svetoslav Ganov50f34d12010-12-03 16:05:40 -080054 * </p>
Svetoslav Ganove9730bf2010-12-20 21:25:20 -080055 * <p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 * For a dialog using this view, see {@link android.app.DatePickerDialog}.
Svetoslav Ganove9730bf2010-12-20 21:25:20 -080057 * </p>
58 *
59 * @attr ref android.R.styleable#DatePicker_startYear
60 * @attr ref android.R.styleable#DatePicker_endYear
61 * @attr ref android.R.styleable#DatePicker_maxDate
62 * @attr ref android.R.styleable#DatePicker_minDate
63 * @attr ref android.R.styleable#DatePicker_spinnersShown
64 * @attr ref android.R.styleable#DatePicker_calendarViewShown
Alan Viveretteba9bf412014-09-03 20:14:21 -070065 * @attr ref android.R.styleable#DatePicker_dayOfWeekBackground
Alan Viverette60727e02014-07-28 16:56:32 -070066 * @attr ref android.R.styleable#DatePicker_dayOfWeekTextAppearance
Alan Viveretteba9bf412014-09-03 20:14:21 -070067 * @attr ref android.R.styleable#DatePicker_headerBackground
Alan Viverette60727e02014-07-28 16:56:32 -070068 * @attr ref android.R.styleable#DatePicker_headerMonthTextAppearance
69 * @attr ref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance
70 * @attr ref android.R.styleable#DatePicker_headerYearTextAppearance
71 * @attr ref android.R.styleable#DatePicker_yearListItemTextAppearance
72 * @attr ref android.R.styleable#DatePicker_yearListSelectorColor
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070073 * @attr ref android.R.styleable#DatePicker_calendarTextColor
Alan Viveretted25eb9f2014-11-24 14:07:24 -080074 * @attr ref android.R.styleable#DatePicker_datePickerMode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 */
76@Widget
77public class DatePicker extends FrameLayout {
Svetoslav Ganove9730bf2010-12-20 21:25:20 -080078 private static final String LOG_TAG = DatePicker.class.getSimpleName();
79
Chet Haase3053b2f2014-08-06 07:51:50 -070080 private static final int MODE_SPINNER = 1;
81 private static final int MODE_CALENDAR = 2;
82
Alan Viverette60727e02014-07-28 16:56:32 -070083 private final DatePickerDelegate mDelegate;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -070084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 /**
Alan Viverette0ef59ac2015-03-23 13:13:25 -070086 * The callback used to indicate the user changed the date.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 */
88 public interface OnDateChangedListener {
89
90 /**
Svetoslav Ganove9730bf2010-12-20 21:25:20 -080091 * Called upon a date change.
92 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 * @param view The view associated with this listener.
94 * @param year The year that was set.
95 * @param monthOfYear The month that was set (0-11) for compatibility
Svetoslav Ganov50f34d12010-12-03 16:05:40 -080096 * with {@link java.util.Calendar}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 * @param dayOfMonth The day of the month that was set.
98 */
99 void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
100 }
101
102 public DatePicker(Context context) {
103 this(context, null);
104 }
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 public DatePicker(Context context, AttributeSet attrs) {
Svetoslav Ganov4243dc32011-01-18 19:39:57 -0800107 this(context, attrs, R.attr.datePickerStyle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 }
109
Alan Viverette617feb92013-09-09 18:09:13 -0700110 public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
111 this(context, attrs, defStyleAttr, 0);
112 }
113
114 public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
115 super(context, attrs, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116
Alan Viverette60727e02014-07-28 16:56:32 -0700117 final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
118 defStyleAttr, defStyleRes);
Alan Viverette518ff0d2014-08-15 14:20:35 -0700119 final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
Alan Viverette0a04bb02014-09-03 20:48:02 -0700120 final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700121 a.recycle();
122
Chet Haase3053b2f2014-08-06 07:51:50 -0700123 switch (mode) {
124 case MODE_CALENDAR:
125 mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
126 break;
127 case MODE_SPINNER:
128 default:
129 mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
130 break;
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700131 }
Alan Viverette0a04bb02014-09-03 20:48:02 -0700132
133 if (firstDayOfWeek != 0) {
134 setFirstDayOfWeek(firstDayOfWeek);
135 }
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700136 }
137
Chet Haase3053b2f2014-08-06 07:51:50 -0700138 private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700139 int defStyleAttr, int defStyleRes) {
Chet Haase3053b2f2014-08-06 07:51:50 -0700140 return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700141 }
142
Chet Haase3053b2f2014-08-06 07:51:50 -0700143 private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs,
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700144 int defStyleAttr, int defStyleRes) {
Chet Haase3053b2f2014-08-06 07:51:50 -0700145 return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr,
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700146 defStyleRes);
147 }
148
149 /**
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800150 * Initialize the state. If the provided values designate an inconsistent
Svetoslav Ganove9730bf2010-12-20 21:25:20 -0800151 * date the values are normalized before updating the spinners.
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800152 *
153 * @param year The initial year.
154 * @param monthOfYear The initial month <strong>starting from zero</strong>.
155 * @param dayOfMonth The initial day of the month.
156 * @param onDateChangedListener How user is notified date is changed by
157 * user, can be null.
158 */
159 public void init(int year, int monthOfYear, int dayOfMonth,
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700160 OnDateChangedListener onDateChangedListener) {
161 mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800162 }
163
164 /**
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700165 * Update the current date.
Svetoslav Ganova911d4a2010-12-08 16:11:30 -0800166 *
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700167 * @param year The year.
168 * @param month The month which is <strong>starting from zero</strong>.
169 * @param dayOfMonth The day of the month.
Svetoslav Ganova911d4a2010-12-08 16:11:30 -0800170 */
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700171 public void updateDate(int year, int month, int dayOfMonth) {
172 mDelegate.updateDate(year, month, dayOfMonth);
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800173 }
174
175 /**
176 * @return The selected year.
177 */
178 public int getYear() {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700179 return mDelegate.getYear();
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800180 }
181
182 /**
183 * @return The selected month.
184 */
185 public int getMonth() {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700186 return mDelegate.getMonth();
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800187 }
188
189 /**
190 * @return The selected day of month.
191 */
192 public int getDayOfMonth() {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700193 return mDelegate.getDayOfMonth();
Svetoslav Ganov50f34d12010-12-03 16:05:40 -0800194 }
195
196 /**
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700197 * Gets the minimal date supported by this {@link DatePicker} in
198 * milliseconds since January 1, 1970 00:00:00 in
199 * {@link TimeZone#getDefault()} time zone.
200 * <p>
201 * Note: The default minimal date is 01/01/1900.
202 * <p>
Svetoslav Ganova53efe92011-09-08 18:08:36 -0700203 *
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700204 * @return The minimal supported date.
Svetoslav Ganova53efe92011-09-08 18:08:36 -0700205 */
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700206 public long getMinDate() {
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700207 return mDelegate.getMinDate().getTimeInMillis();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700208 }
209
210 /**
211 * Sets the minimal date supported by this {@link NumberPicker} in
212 * milliseconds since January 1, 1970 00:00:00 in
213 * {@link TimeZone#getDefault()} time zone.
214 *
215 * @param minDate The minimal supported date.
216 */
217 public void setMinDate(long minDate) {
218 mDelegate.setMinDate(minDate);
219 }
220
221 /**
222 * Gets the maximal date supported by this {@link DatePicker} in
223 * milliseconds since January 1, 1970 00:00:00 in
224 * {@link TimeZone#getDefault()} time zone.
225 * <p>
226 * Note: The default maximal date is 12/31/2100.
227 * <p>
228 *
229 * @return The maximal supported date.
230 */
231 public long getMaxDate() {
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700232 return mDelegate.getMaxDate().getTimeInMillis();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700233 }
234
235 /**
236 * Sets the maximal date supported by this {@link DatePicker} in
237 * milliseconds since January 1, 1970 00:00:00 in
238 * {@link TimeZone#getDefault()} time zone.
239 *
240 * @param maxDate The maximal supported date.
241 */
242 public void setMaxDate(long maxDate) {
243 mDelegate.setMaxDate(maxDate);
244 }
245
Alan Viverette518ff0d2014-08-15 14:20:35 -0700246 /**
247 * Sets the callback that indicates the current date is valid.
248 *
249 * @param callback the callback, may be null
250 * @hide
251 */
252 public void setValidationCallback(@Nullable ValidationCallback callback) {
253 mDelegate.setValidationCallback(callback);
254 }
255
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700256 @Override
257 public void setEnabled(boolean enabled) {
258 if (mDelegate.isEnabled() == enabled) {
259 return;
Svetoslav Ganova53efe92011-09-08 18:08:36 -0700260 }
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700261 super.setEnabled(enabled);
262 mDelegate.setEnabled(enabled);
Svetoslav Ganova53efe92011-09-08 18:08:36 -0700263 }
264
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700265 @Override
266 public boolean isEnabled() {
267 return mDelegate.isEnabled();
Svetoslav Ganovd11e6152012-03-20 12:13:02 -0700268 }
269
Alan Viverettea54956a2015-01-07 16:05:02 -0800270 /** @hide */
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700271 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800272 public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700273 return mDelegate.dispatchPopulateAccessibilityEvent(event);
274 }
275
Alan Viverettea54956a2015-01-07 16:05:02 -0800276 /** @hide */
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700277 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800278 public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
279 super.onPopulateAccessibilityEventInternal(event);
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700280 mDelegate.onPopulateAccessibilityEvent(event);
281 }
282
283 @Override
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800284 public CharSequence getAccessibilityClassName() {
285 return DatePicker.class.getName();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700286 }
287
288 @Override
289 protected void onConfigurationChanged(Configuration newConfig) {
290 super.onConfigurationChanged(newConfig);
291 mDelegate.onConfigurationChanged(newConfig);
292 }
293
294 /**
Alan Viverette0a04bb02014-09-03 20:48:02 -0700295 * Sets the first day of week.
296 *
297 * @param firstDayOfWeek The first day of the week conforming to the
298 * {@link CalendarView} APIs.
299 * @see Calendar#SUNDAY
300 * @see Calendar#MONDAY
301 * @see Calendar#TUESDAY
302 * @see Calendar#WEDNESDAY
303 * @see Calendar#THURSDAY
304 * @see Calendar#FRIDAY
305 * @see Calendar#SATURDAY
306 *
307 * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
308 */
309 public void setFirstDayOfWeek(int firstDayOfWeek) {
310 if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
311 throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
312 }
313 mDelegate.setFirstDayOfWeek(firstDayOfWeek);
314 }
315
316 /**
317 * Gets the first day of week.
318 *
319 * @return The first day of the week conforming to the {@link CalendarView}
320 * APIs.
321 * @see Calendar#SUNDAY
322 * @see Calendar#MONDAY
323 * @see Calendar#TUESDAY
324 * @see Calendar#WEDNESDAY
325 * @see Calendar#THURSDAY
326 * @see Calendar#FRIDAY
327 * @see Calendar#SATURDAY
328 *
329 * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
330 */
331 public int getFirstDayOfWeek() {
332 return mDelegate.getFirstDayOfWeek();
333 }
334
335 /**
Alan Viverette452fe342015-03-23 14:26:09 -0700336 * Returns whether the {@link CalendarView} is shown.
337 * <p>
338 * <strong>Note:</strong> This method returns {@code false} when the
339 * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
340 * to {@code calendar}.
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700341 *
Alan Viverette452fe342015-03-23 14:26:09 -0700342 * @return {@code true} if the calendar view is shown
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700343 * @see #getCalendarView()
344 */
345 public boolean getCalendarViewShown() {
346 return mDelegate.getCalendarViewShown();
347 }
348
349 /**
Alan Viverette452fe342015-03-23 14:26:09 -0700350 * Returns the {@link CalendarView} used by this picker.
Alan Viveretted25eb9f2014-11-24 14:07:24 -0800351 * <p>
Alan Viverette452fe342015-03-23 14:26:09 -0700352 * <strong>Note:</strong> This method returns {@code null} when the
Alan Viveretted25eb9f2014-11-24 14:07:24 -0800353 * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
354 * to {@code calendar}.
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700355 *
Alan Viverette452fe342015-03-23 14:26:09 -0700356 * @return the calendar view
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700357 * @see #getCalendarViewShown()
358 */
Alan Viverette0a04bb02014-09-03 20:48:02 -0700359 public CalendarView getCalendarView() {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700360 return mDelegate.getCalendarView();
361 }
362
363 /**
364 * Sets whether the {@link CalendarView} is shown.
Alan Viveretted25eb9f2014-11-24 14:07:24 -0800365 * <p>
Alan Viverette452fe342015-03-23 14:26:09 -0700366 * <strong>Note:</strong> Calling this method has no effect when the
Alan Viveretted25eb9f2014-11-24 14:07:24 -0800367 * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
368 * to {@code calendar}.
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700369 *
Alan Viverette452fe342015-03-23 14:26:09 -0700370 * @param shown {@code true} to show the calendar view, {@code false} to
371 * hide it
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700372 */
373 public void setCalendarViewShown(boolean shown) {
374 mDelegate.setCalendarViewShown(shown);
375 }
376
377 /**
Alan Viverette452fe342015-03-23 14:26:09 -0700378 * Returns whether the spinners are shown.
379 * <p>
Alan Viverette835d7982015-03-23 14:54:14 -0700380 * <strong>Note:</strong> his method returns {@code false} when the
Alan Viverette452fe342015-03-23 14:26:09 -0700381 * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
382 * to {@code calendar}.
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700383 *
Alan Viverette452fe342015-03-23 14:26:09 -0700384 * @return {@code true} if the spinners are shown
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700385 */
386 public boolean getSpinnersShown() {
387 return mDelegate.getSpinnersShown();
388 }
389
390 /**
391 * Sets whether the spinners are shown.
Alan Viverette452fe342015-03-23 14:26:09 -0700392 * <p>
393 * Calling this method has no effect when the
394 * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
395 * to {@code calendar}.
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700396 *
Alan Viverette452fe342015-03-23 14:26:09 -0700397 * @param shown {@code true} to show the spinners, {@code false} to hide
398 * them
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700399 */
400 public void setSpinnersShown(boolean shown) {
401 mDelegate.setSpinnersShown(shown);
402 }
403
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700404 @Override
405 protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
Alan Viveretted015e342014-09-15 19:27:55 -0700406 dispatchThawSelfOnly(container);
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700407 }
408
409 @Override
410 protected Parcelable onSaveInstanceState() {
411 Parcelable superState = super.onSaveInstanceState();
412 return mDelegate.onSaveInstanceState(superState);
413 }
414
415 @Override
416 protected void onRestoreInstanceState(Parcelable state) {
Craig Mautnera67d9092014-09-16 15:38:47 -0700417 BaseSavedState ss = (BaseSavedState) state;
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700418 super.onRestoreInstanceState(ss.getSuperState());
419 mDelegate.onRestoreInstanceState(ss);
420 }
421
422 /**
423 * A delegate interface that defined the public API of the DatePicker. Allows different
424 * DatePicker implementations. This would need to be implemented by the DatePicker delegates
425 * for the real behavior.
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700426 *
427 * @hide
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700428 */
429 interface DatePickerDelegate {
430 void init(int year, int monthOfYear, int dayOfMonth,
431 OnDateChangedListener onDateChangedListener);
432
433 void updateDate(int year, int month, int dayOfMonth);
434
435 int getYear();
436 int getMonth();
437 int getDayOfMonth();
438
Alan Viverette0a04bb02014-09-03 20:48:02 -0700439 void setFirstDayOfWeek(int firstDayOfWeek);
440 int getFirstDayOfWeek();
441
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700442 void setMinDate(long minDate);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700443 Calendar getMinDate();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700444
445 void setMaxDate(long maxDate);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700446 Calendar getMaxDate();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700447
448 void setEnabled(boolean enabled);
449 boolean isEnabled();
450
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700451 CalendarView getCalendarView();
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700452
453 void setCalendarViewShown(boolean shown);
454 boolean getCalendarViewShown();
455
456 void setSpinnersShown(boolean shown);
457 boolean getSpinnersShown();
458
Alan Viverette518ff0d2014-08-15 14:20:35 -0700459 void setValidationCallback(ValidationCallback callback);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700460
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700461 void onConfigurationChanged(Configuration newConfig);
462
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700463 Parcelable onSaveInstanceState(Parcelable superState);
464 void onRestoreInstanceState(Parcelable state);
465
466 boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
467 void onPopulateAccessibilityEvent(AccessibilityEvent event);
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700468 }
469
470 /**
471 * An abstract class which can be used as a start for DatePicker implementations
472 */
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700473 abstract static class AbstractDatePickerDelegate implements DatePickerDelegate {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700474 // The delegator
475 protected DatePicker mDelegator;
476
477 // The context
478 protected Context mContext;
479
480 // The current locale
481 protected Locale mCurrentLocale;
482
483 // Callbacks
Alan Viverette518ff0d2014-08-15 14:20:35 -0700484 protected OnDateChangedListener mOnDateChangedListener;
485 protected ValidationCallback mValidationCallback;
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700486
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700487 public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700488 mDelegator = delegator;
489 mContext = context;
490
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700491 setCurrentLocale(Locale.getDefault());
492 }
493
494 protected void setCurrentLocale(Locale locale) {
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700495 if (!locale.equals(mCurrentLocale)) {
496 mCurrentLocale = locale;
497 onLocaleChanged(locale);
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700498 }
Svetoslav Ganovd11e6152012-03-20 12:13:02 -0700499 }
Alan Viverette518ff0d2014-08-15 14:20:35 -0700500
501 @Override
502 public void setValidationCallback(ValidationCallback callback) {
503 mValidationCallback = callback;
504 }
505
506 protected void onValidationChanged(boolean valid) {
507 if (mValidationCallback != null) {
508 mValidationCallback.onValidationChanged(valid);
509 }
510 }
Alan Viverette0ef59ac2015-03-23 13:13:25 -0700511
512 protected void onLocaleChanged(Locale locale) {
513 // Stub.
514 }
Alan Viverette6b3f85f2016-03-01 16:48:04 -0500515
516 /**
517 * Class for managing state storing/restoring.
518 */
519 static class SavedState extends View.BaseSavedState {
520 private final int mSelectedYear;
521 private final int mSelectedMonth;
522 private final int mSelectedDay;
523 private final long mMinDate;
524 private final long mMaxDate;
525 private final int mCurrentView;
526 private final int mListPosition;
527 private final int mListPositionOffset;
528
529 public SavedState(Parcelable superState, int year, int month, int day, long minDate,
530 long maxDate) {
531 this(superState, year, month, day, minDate, maxDate, 0, 0, 0);
532 }
533
534 /**
535 * Constructor called from {@link DatePicker#onSaveInstanceState()}
536 */
537 public SavedState(Parcelable superState, int year, int month, int day, long minDate,
538 long maxDate, int currentView, int listPosition, int listPositionOffset) {
539 super(superState);
540 mSelectedYear = year;
541 mSelectedMonth = month;
542 mSelectedDay = day;
543 mMinDate = minDate;
544 mMaxDate = maxDate;
545 mCurrentView = currentView;
546 mListPosition = listPosition;
547 mListPositionOffset = listPositionOffset;
548 }
549
550 /**
551 * Constructor called from {@link #CREATOR}
552 */
553 private SavedState(Parcel in) {
554 super(in);
555 mSelectedYear = in.readInt();
556 mSelectedMonth = in.readInt();
557 mSelectedDay = in.readInt();
558 mMinDate = in.readLong();
559 mMaxDate = in.readLong();
560 mCurrentView = in.readInt();
561 mListPosition = in.readInt();
562 mListPositionOffset = in.readInt();
563 }
564
565 @Override
566 public void writeToParcel(Parcel dest, int flags) {
567 super.writeToParcel(dest, flags);
568 dest.writeInt(mSelectedYear);
569 dest.writeInt(mSelectedMonth);
570 dest.writeInt(mSelectedDay);
571 dest.writeLong(mMinDate);
572 dest.writeLong(mMaxDate);
573 dest.writeInt(mCurrentView);
574 dest.writeInt(mListPosition);
575 dest.writeInt(mListPositionOffset);
576 }
577
578 public int getSelectedDay() {
579 return mSelectedDay;
580 }
581
582 public int getSelectedMonth() {
583 return mSelectedMonth;
584 }
585
586 public int getSelectedYear() {
587 return mSelectedYear;
588 }
589
590 public long getMinDate() {
591 return mMinDate;
592 }
593
594 public long getMaxDate() {
595 return mMaxDate;
596 }
597
598 public int getCurrentView() {
599 return mCurrentView;
600 }
601
602 public int getListPosition() {
603 return mListPosition;
604 }
605
606 public int getListPositionOffset() {
607 return mListPositionOffset;
608 }
609
610 @SuppressWarnings("all")
611 // suppress unused and hiding
612 public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
613
614 public SavedState createFromParcel(Parcel in) {
615 return new SavedState(in);
616 }
617
618 public SavedState[] newArray(int size) {
619 return new SavedState[size];
620 }
621 };
622 }
Svetoslav Ganova53efe92011-09-08 18:08:36 -0700623 }
624
Fabrice Di Meglio039a7842013-08-28 17:41:26 -0700625 /**
Alan Viverette518ff0d2014-08-15 14:20:35 -0700626 * A callback interface for updating input validity when the date picker
627 * when included into a dialog.
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700628 *
629 * @hide
630 */
Alan Viverette6b3f85f2016-03-01 16:48:04 -0500631 public interface ValidationCallback {
Alan Viverette518ff0d2014-08-15 14:20:35 -0700632 void onValidationChanged(boolean valid);
Fabrice Di Megliobd9152f2013-10-01 11:21:31 -0700633 }
Svetoslav Ganov3fec3fe2011-09-01 14:48:37 -0700634}