2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.widget;
19 import android.content.Context;
20 import android.content.res.ColorStateList;
21 import android.content.res.Configuration;
22 import android.content.res.Resources;
23 import android.content.res.TypedArray;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.text.format.DateFormat;
27 import android.text.format.DateUtils;
28 import android.util.AttributeSet;
29 import android.view.HapticFeedbackConstants;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.view.accessibility.AccessibilityEvent;
33 import android.view.accessibility.AccessibilityNodeInfo;
34 import android.view.animation.AlphaAnimation;
35 import android.view.animation.Animation;
37 import com.android.internal.R;
38 import com.android.internal.widget.AccessibleDateAnimator;
40 import java.text.SimpleDateFormat;
41 import java.util.Calendar;
42 import java.util.HashSet;
43 import java.util.Locale;
46 * A delegate for picking up a date (day / month / year).
48 class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate implements
49 View.OnClickListener, DatePickerController {
50 private static final int USE_LOCALE = 0;
52 private static final int UNINITIALIZED = -1;
53 private static final int MONTH_AND_DAY_VIEW = 0;
54 private static final int YEAR_VIEW = 1;
56 private static final int DEFAULT_START_YEAR = 1900;
57 private static final int DEFAULT_END_YEAR = 2100;
59 private static final int ANIMATION_DURATION = 300;
61 private static final int MONTH_INDEX = 0;
62 private static final int DAY_INDEX = 1;
63 private static final int YEAR_INDEX = 2;
65 private SimpleDateFormat mYearFormat = new SimpleDateFormat("y", Locale.getDefault());
66 private SimpleDateFormat mDayFormat = new SimpleDateFormat("d", Locale.getDefault());
68 private TextView mDayOfWeekView;
70 /** Layout that contains the current month, day, and year. */
71 private LinearLayout mMonthDayYearLayout;
73 /** Clickable layout that contains the current day and year. */
74 private LinearLayout mMonthAndDayLayout;
76 private TextView mHeaderMonthTextView;
77 private TextView mHeaderDayOfMonthTextView;
78 private TextView mHeaderYearTextView;
79 private DayPickerView mDayPickerView;
80 private YearPickerView mYearPickerView;
82 private boolean mIsEnabled = true;
84 // Accessibility strings.
85 private String mDayPickerDescription;
86 private String mSelectDay;
87 private String mYearPickerDescription;
88 private String mSelectYear;
90 private AccessibleDateAnimator mAnimator;
92 private DatePicker.OnDateChangedListener mDateChangedListener;
94 private int mCurrentView = UNINITIALIZED;
96 private Calendar mCurrentDate;
97 private Calendar mTempDate;
98 private Calendar mMinDate;
99 private Calendar mMaxDate;
101 private int mFirstDayOfWeek = USE_LOCALE;
103 private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
105 public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
106 int defStyleAttr, int defStyleRes) {
107 super(delegator, context);
109 final Locale locale = Locale.getDefault();
110 mMinDate = getCalendarForLocale(mMinDate, locale);
111 mMaxDate = getCalendarForLocale(mMaxDate, locale);
112 mTempDate = getCalendarForLocale(mMaxDate, locale);
113 mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
115 mMinDate.set(DEFAULT_START_YEAR, 1, 1);
116 mMaxDate.set(DEFAULT_END_YEAR, 12, 31);
118 final Resources res = mDelegator.getResources();
119 final TypedArray a = mContext.obtainStyledAttributes(attrs,
120 R.styleable.DatePicker, defStyleAttr, defStyleRes);
121 final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
122 Context.LAYOUT_INFLATER_SERVICE);
123 final int layoutResourceId = a.getResourceId(
124 R.styleable.DatePicker_internalLayout, R.layout.date_picker_holo);
125 final View mainView = inflater.inflate(layoutResourceId, null);
126 mDelegator.addView(mainView);
128 mDayOfWeekView = (TextView) mainView.findViewById(R.id.date_picker_header);
130 // Layout that contains the current date and day name header.
131 final LinearLayout dateLayout = (LinearLayout) mainView.findViewById(
132 R.id.day_picker_selector_layout);
133 mMonthDayYearLayout = (LinearLayout) mainView.findViewById(
134 R.id.date_picker_month_day_year_layout);
135 mMonthAndDayLayout = (LinearLayout) mainView.findViewById(
136 R.id.date_picker_month_and_day_layout);
137 mMonthAndDayLayout.setOnClickListener(this);
138 mHeaderMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_month);
139 mHeaderDayOfMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_day);
140 mHeaderYearTextView = (TextView) mainView.findViewById(R.id.date_picker_year);
141 mHeaderYearTextView.setOnClickListener(this);
143 // Obtain default highlight color from the theme.
144 final int defaultHighlightColor = mHeaderYearTextView.getHighlightColor();
146 // Use Theme attributes if possible
147 final int dayOfWeekTextAppearanceResId = a.getResourceId(
148 R.styleable.DatePicker_dayOfWeekTextAppearance, -1);
149 if (dayOfWeekTextAppearanceResId != -1) {
150 mDayOfWeekView.setTextAppearance(context, dayOfWeekTextAppearanceResId);
153 mDayOfWeekView.setBackground(a.getDrawable(R.styleable.DatePicker_dayOfWeekBackground));
155 dateLayout.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
157 final int headerSelectedTextColor = a.getColor(
158 R.styleable.DatePicker_headerSelectedTextColor, defaultHighlightColor);
159 final int monthTextAppearanceResId = a.getResourceId(
160 R.styleable.DatePicker_headerMonthTextAppearance, -1);
161 if (monthTextAppearanceResId != -1) {
162 mHeaderMonthTextView.setTextAppearance(context, monthTextAppearanceResId);
164 mHeaderMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
165 mHeaderMonthTextView.getTextColors(), R.attr.state_selected,
166 headerSelectedTextColor));
168 final int dayOfMonthTextAppearanceResId = a.getResourceId(
169 R.styleable.DatePicker_headerDayOfMonthTextAppearance, -1);
170 if (dayOfMonthTextAppearanceResId != -1) {
171 mHeaderDayOfMonthTextView.setTextAppearance(context, dayOfMonthTextAppearanceResId);
173 mHeaderDayOfMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
174 mHeaderDayOfMonthTextView.getTextColors(), R.attr.state_selected,
175 headerSelectedTextColor));
177 final int yearTextAppearanceResId = a.getResourceId(
178 R.styleable.DatePicker_headerYearTextAppearance, -1);
179 if (yearTextAppearanceResId != -1) {
180 mHeaderYearTextView.setTextAppearance(context, yearTextAppearanceResId);
182 mHeaderYearTextView.setTextColor(ColorStateList.addFirstIfMissing(
183 mHeaderYearTextView.getTextColors(), R.attr.state_selected,
184 headerSelectedTextColor));
186 mDayPickerView = new DayPickerView(mContext);
187 mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
188 mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
189 mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
190 mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
191 mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
193 mYearPickerView = new YearPickerView(mContext);
194 mYearPickerView.init(this);
195 mYearPickerView.setRange(mMinDate, mMaxDate);
197 final int yearSelectedCircleColor = a.getColor(R.styleable.DatePicker_yearListSelectorColor,
198 defaultHighlightColor);
199 mYearPickerView.setYearSelectedCircleColor(yearSelectedCircleColor);
201 final ColorStateList calendarTextColor = a.getColorStateList(
202 R.styleable.DatePicker_calendarTextColor);
203 final int calendarSelectedTextColor = a.getColor(
204 R.styleable.DatePicker_calendarSelectedTextColor, defaultHighlightColor);
205 mDayPickerView.setCalendarTextColor(ColorStateList.addFirstIfMissing(
206 calendarTextColor, R.attr.state_selected, calendarSelectedTextColor));
208 mDayPickerDescription = res.getString(R.string.day_picker_description);
209 mSelectDay = res.getString(R.string.select_day);
210 mYearPickerDescription = res.getString(R.string.year_picker_description);
211 mSelectYear = res.getString(R.string.select_year);
213 mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
214 mAnimator.addView(mDayPickerView);
215 mAnimator.addView(mYearPickerView);
216 mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
218 final Animation animation = new AlphaAnimation(0.0f, 1.0f);
219 animation.setDuration(ANIMATION_DURATION);
220 mAnimator.setInAnimation(animation);
222 final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
223 animation2.setDuration(ANIMATION_DURATION);
224 mAnimator.setOutAnimation(animation2);
226 updateDisplay(false);
227 setCurrentView(MONTH_AND_DAY_VIEW);
231 * Gets a calendar for locale bootstrapped with the value of a given calendar.
233 * @param oldCalendar The old calendar.
234 * @param locale The locale.
236 private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
237 if (oldCalendar == null) {
238 return Calendar.getInstance(locale);
240 final long currentTimeMillis = oldCalendar.getTimeInMillis();
241 Calendar newCalendar = Calendar.getInstance(locale);
242 newCalendar.setTimeInMillis(currentTimeMillis);
248 * Compute the array representing the order of Month / Day / Year views in their layout.
249 * Will be used for I18N purpose as the order of them depends on the Locale.
251 private int[] getMonthDayYearIndexes(String pattern) {
252 int[] result = new int[3];
254 final String filteredPattern = pattern.replaceAll("'.*?'", "");
256 final int dayIndex = filteredPattern.indexOf('d');
257 final int monthMIndex = filteredPattern.indexOf("M");
258 final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
259 final int yearIndex = filteredPattern.indexOf("y");
261 if (yearIndex < monthIndex) {
262 result[YEAR_INDEX] = 0;
264 if (monthIndex < dayIndex) {
265 result[MONTH_INDEX] = 1;
266 result[DAY_INDEX] = 2;
268 result[MONTH_INDEX] = 2;
269 result[DAY_INDEX] = 1;
272 result[YEAR_INDEX] = 2;
274 if (monthIndex < dayIndex) {
275 result[MONTH_INDEX] = 0;
276 result[DAY_INDEX] = 1;
278 result[MONTH_INDEX] = 1;
279 result[DAY_INDEX] = 0;
285 private void updateDisplay(boolean announce) {
286 if (mDayOfWeekView != null) {
287 mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
288 Locale.getDefault()));
291 // Compute indices of Month, Day and Year views
292 final String bestDateTimePattern =
293 DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
294 final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
296 // Position the Year and MonthAndDay views within the header.
297 mMonthDayYearLayout.removeAllViews();
298 if (viewIndices[YEAR_INDEX] == 0) {
299 mMonthDayYearLayout.addView(mHeaderYearTextView);
300 mMonthDayYearLayout.addView(mMonthAndDayLayout);
302 mMonthDayYearLayout.addView(mMonthAndDayLayout);
303 mMonthDayYearLayout.addView(mHeaderYearTextView);
306 // Position Day and Month views within the MonthAndDay view.
307 mMonthAndDayLayout.removeAllViews();
308 if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
309 mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
310 mMonthAndDayLayout.addView(mHeaderMonthTextView);
312 mMonthAndDayLayout.addView(mHeaderMonthTextView);
313 mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
316 mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
317 Locale.getDefault()).toUpperCase(Locale.getDefault()));
318 mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
319 mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
322 long millis = mCurrentDate.getTimeInMillis();
323 mAnimator.setDateMillis(millis);
324 int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
325 String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
326 mMonthAndDayLayout.setContentDescription(monthAndDayText);
329 flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
330 String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
331 mAnimator.announceForAccessibility(fullDateText);
335 private void setCurrentView(final int viewIndex) {
336 long millis = mCurrentDate.getTimeInMillis();
339 case MONTH_AND_DAY_VIEW:
340 mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
341 if (mCurrentView != viewIndex) {
342 mMonthAndDayLayout.setSelected(true);
343 mHeaderYearTextView.setSelected(false);
344 mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
345 mCurrentView = viewIndex;
348 final int flags = DateUtils.FORMAT_SHOW_DATE;
349 final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
350 mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
351 mAnimator.announceForAccessibility(mSelectDay);
354 mYearPickerView.onDateChanged();
355 if (mCurrentView != viewIndex) {
356 mMonthAndDayLayout.setSelected(false);
357 mHeaderYearTextView.setSelected(true);
358 mAnimator.setDisplayedChild(YEAR_VIEW);
359 mCurrentView = viewIndex;
362 final CharSequence yearString = mYearFormat.format(millis);
363 mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
364 mAnimator.announceForAccessibility(mSelectYear);
370 public void init(int year, int monthOfYear, int dayOfMonth,
371 DatePicker.OnDateChangedListener callBack) {
372 mCurrentDate.set(Calendar.YEAR, year);
373 mCurrentDate.set(Calendar.MONTH, monthOfYear);
374 mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
376 mDateChangedListener = callBack;
378 onDateChanged(false, false);
382 public void updateDate(int year, int month, int dayOfMonth) {
383 mCurrentDate.set(Calendar.YEAR, year);
384 mCurrentDate.set(Calendar.MONTH, month);
385 mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
387 onDateChanged(false, true);
390 private void onDateChanged(boolean fromUser, boolean callbackToClient) {
391 if (callbackToClient && mDateChangedListener != null) {
392 final int year = mCurrentDate.get(Calendar.YEAR);
393 final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
394 final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
395 mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
398 for (OnDateChangedListener listener : mListeners) {
399 listener.onDateChanged();
402 mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
404 updateDisplay(fromUser);
412 public int getYear() {
413 return mCurrentDate.get(Calendar.YEAR);
417 public int getMonth() {
418 return mCurrentDate.get(Calendar.MONTH);
422 public int getDayOfMonth() {
423 return mCurrentDate.get(Calendar.DAY_OF_MONTH);
427 public void setMinDate(long minDate) {
428 mTempDate.setTimeInMillis(minDate);
429 if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
430 && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
433 if (mCurrentDate.before(mTempDate)) {
434 mCurrentDate.setTimeInMillis(minDate);
435 onDateChanged(false, true);
437 mMinDate.setTimeInMillis(minDate);
438 mDayPickerView.setMinDate(minDate);
439 mYearPickerView.setRange(mMinDate, mMaxDate);
443 public Calendar getMinDate() {
448 public void setMaxDate(long maxDate) {
449 mTempDate.setTimeInMillis(maxDate);
450 if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
451 && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
454 if (mCurrentDate.after(mTempDate)) {
455 mCurrentDate.setTimeInMillis(maxDate);
456 onDateChanged(false, true);
458 mMaxDate.setTimeInMillis(maxDate);
459 mDayPickerView.setMaxDate(maxDate);
460 mYearPickerView.setRange(mMinDate, mMaxDate);
464 public Calendar getMaxDate() {
469 public void setFirstDayOfWeek(int firstDayOfWeek) {
470 mFirstDayOfWeek = firstDayOfWeek;
472 mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
476 public int getFirstDayOfWeek() {
477 if (mFirstDayOfWeek != USE_LOCALE) {
478 return mFirstDayOfWeek;
480 return mCurrentDate.getFirstDayOfWeek();
484 public void setEnabled(boolean enabled) {
485 mMonthAndDayLayout.setEnabled(enabled);
486 mHeaderYearTextView.setEnabled(enabled);
487 mAnimator.setEnabled(enabled);
488 mIsEnabled = enabled;
492 public boolean isEnabled() {
497 public CalendarView getCalendarView() {
498 throw new UnsupportedOperationException(
499 "CalendarView does not exists for the new DatePicker");
503 public void setCalendarViewShown(boolean shown) {
504 // No-op for compatibility with the old DatePicker.
508 public boolean getCalendarViewShown() {
513 public void setSpinnersShown(boolean shown) {
514 // No-op for compatibility with the old DatePicker.
518 public boolean getSpinnersShown() {
523 public void onConfigurationChanged(Configuration newConfig) {
524 mYearFormat = new SimpleDateFormat("y", newConfig.locale);
525 mDayFormat = new SimpleDateFormat("d", newConfig.locale);
529 public Parcelable onSaveInstanceState(Parcelable superState) {
530 final int year = mCurrentDate.get(Calendar.YEAR);
531 final int month = mCurrentDate.get(Calendar.MONTH);
532 final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
534 int listPosition = -1;
535 int listPositionOffset = -1;
537 if (mCurrentView == MONTH_AND_DAY_VIEW) {
538 listPosition = mDayPickerView.getMostVisiblePosition();
539 } else if (mCurrentView == YEAR_VIEW) {
540 listPosition = mYearPickerView.getFirstVisiblePosition();
541 listPositionOffset = mYearPickerView.getFirstPositionOffset();
544 return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
545 mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
549 public void onRestoreInstanceState(Parcelable state) {
550 SavedState ss = (SavedState) state;
552 mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
553 mCurrentView = ss.getCurrentView();
554 mMinDate.setTimeInMillis(ss.getMinDate());
555 mMaxDate.setTimeInMillis(ss.getMaxDate());
557 updateDisplay(false);
558 setCurrentView(mCurrentView);
560 final int listPosition = ss.getListPosition();
561 if (listPosition != -1) {
562 if (mCurrentView == MONTH_AND_DAY_VIEW) {
563 mDayPickerView.postSetSelection(listPosition);
564 } else if (mCurrentView == YEAR_VIEW) {
565 mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
571 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
572 onPopulateAccessibilityEvent(event);
577 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
578 event.getText().add(mCurrentDate.getTime().toString());
582 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
583 event.setClassName(DatePicker.class.getName());
587 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
588 info.setClassName(DatePicker.class.getName());
592 public void onYearSelected(int year) {
593 adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
594 mCurrentDate.set(Calendar.YEAR, year);
595 onDateChanged(true, true);
597 // Auto-advance to month and day view.
598 setCurrentView(MONTH_AND_DAY_VIEW);
601 // If the newly selected month / year does not contain the currently selected day number,
602 // change the selected day number to the last day of the selected month or year.
603 // e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
604 // e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
605 private void adjustDayInMonthIfNeeded(int month, int year) {
606 int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
607 int daysInMonth = getDaysInMonth(month, year);
608 if (day > daysInMonth) {
609 mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
613 public static int getDaysInMonth(int month, int year) {
615 case Calendar.JANUARY:
619 case Calendar.AUGUST:
620 case Calendar.OCTOBER:
621 case Calendar.DECEMBER:
625 case Calendar.SEPTEMBER:
626 case Calendar.NOVEMBER:
628 case Calendar.FEBRUARY:
629 return (year % 4 == 0) ? 29 : 28;
631 throw new IllegalArgumentException("Invalid Month");
636 public void registerOnDateChangedListener(OnDateChangedListener listener) {
637 mListeners.add(listener);
641 public Calendar getSelectedDay() {
646 public void tryVibrate() {
647 mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
651 public void onClick(View v) {
653 if (v.getId() == R.id.date_picker_year) {
654 setCurrentView(YEAR_VIEW);
655 } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
656 setCurrentView(MONTH_AND_DAY_VIEW);
661 * Listener called when the user selects a day in the day picker view.
663 private final DayPickerView.OnDaySelectedListener
664 mOnDaySelectedListener = new DayPickerView.OnDaySelectedListener() {
666 public void onDaySelected(DayPickerView view, Calendar day) {
667 mCurrentDate.setTimeInMillis(day.getTimeInMillis());
668 onDateChanged(true, true);
673 * Class for managing state storing/restoring.
675 private static class SavedState extends View.BaseSavedState {
677 private final int mSelectedYear;
678 private final int mSelectedMonth;
679 private final int mSelectedDay;
680 private final long mMinDate;
681 private final long mMaxDate;
682 private final int mCurrentView;
683 private final int mListPosition;
684 private final int mListPositionOffset;
687 * Constructor called from {@link DatePicker#onSaveInstanceState()}
689 private SavedState(Parcelable superState, int year, int month, int day,
690 long minDate, long maxDate, int currentView, int listPosition,
691 int listPositionOffset) {
693 mSelectedYear = year;
694 mSelectedMonth = month;
698 mCurrentView = currentView;
699 mListPosition = listPosition;
700 mListPositionOffset = listPositionOffset;
704 * Constructor called from {@link #CREATOR}
706 private SavedState(Parcel in) {
708 mSelectedYear = in.readInt();
709 mSelectedMonth = in.readInt();
710 mSelectedDay = in.readInt();
711 mMinDate = in.readLong();
712 mMaxDate = in.readLong();
713 mCurrentView = in.readInt();
714 mListPosition = in.readInt();
715 mListPositionOffset = in.readInt();
719 public void writeToParcel(Parcel dest, int flags) {
720 super.writeToParcel(dest, flags);
721 dest.writeInt(mSelectedYear);
722 dest.writeInt(mSelectedMonth);
723 dest.writeInt(mSelectedDay);
724 dest.writeLong(mMinDate);
725 dest.writeLong(mMaxDate);
726 dest.writeInt(mCurrentView);
727 dest.writeInt(mListPosition);
728 dest.writeInt(mListPositionOffset);
731 public int getSelectedDay() {
735 public int getSelectedMonth() {
736 return mSelectedMonth;
739 public int getSelectedYear() {
740 return mSelectedYear;
743 public long getMinDate() {
747 public long getMaxDate() {
751 public int getCurrentView() {
755 public int getListPosition() {
756 return mListPosition;
759 public int getListPositionOffset() {
760 return mListPositionOffset;
763 @SuppressWarnings("all")
764 // suppress unused and hiding
765 public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
767 public SavedState createFromParcel(Parcel in) {
768 return new SavedState(in);
771 public SavedState[] newArray(int size) {
772 return new SavedState[size];