DatePickerCalendarDelegate.java revision 50eb025c2fea7e364e0be951ce8ba6ca605f901a
1bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/*
2bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Copyright (C) 2014 The Android Open Source Project
3bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
4bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
5bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * you may not use this file except in compliance with the License.
6bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * You may obtain a copy of the License at
7bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
8bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
9bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio *
10bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
11bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
12bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * See the License for the specific language governing permissions and
14bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * limitations under the License.
15bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */
16bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
17bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Megliopackage android.widget;
18bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
19bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.Context;
20bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.ColorStateList;
21bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Configuration;
22bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Resources;
23bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.TypedArray;
24bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcel;
25bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcelable;
26bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateFormat;
27bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateUtils;
28bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.util.AttributeSet;
29bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.HapticFeedbackConstants;
30bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.LayoutInflater;
31bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.View;
32bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityEvent;
33bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityNodeInfo;
34bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.animation.AlphaAnimation;
35bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.animation.Animation;
36bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
37bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport com.android.internal.R;
38bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport com.android.internal.widget.AccessibleDateAnimator;
39bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
40bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.text.SimpleDateFormat;
41bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Calendar;
42bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.HashSet;
43bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Locale;
44bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
45bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/**
46bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * A delegate for picking up a date (day / month / year).
47bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */
483053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haaseclass DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate implements
49bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        View.OnClickListener, DatePickerController {
500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private static final int USE_LOCALE = 0;
51bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
52bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int UNINITIALIZED = -1;
53bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int MONTH_AND_DAY_VIEW = 0;
54bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int YEAR_VIEW = 1;
55bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
56bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_START_YEAR = 1900;
57bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_END_YEAR = 2100;
58bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
59bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int ANIMATION_DURATION = 300;
60bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
61bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int MONTH_INDEX = 0;
62bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DAY_INDEX = 1;
63bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int YEAR_INDEX = 2;
64bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
65bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private SimpleDateFormat mYearFormat = new SimpleDateFormat("y", Locale.getDefault());
66bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private SimpleDateFormat mDayFormat = new SimpleDateFormat("d", Locale.getDefault());
67bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
68bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private TextView mDayOfWeekView;
697119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
707119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    /** Layout that contains the current month, day, and year. */
717119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    private LinearLayout mMonthDayYearLayout;
727119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
737119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    /** Clickable layout that contains the current day and year. */
74bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private LinearLayout mMonthAndDayLayout;
757119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
7660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderMonthTextView;
7760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderDayOfMonthTextView;
7860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderYearTextView;
79bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DayPickerView mDayPickerView;
80bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private YearPickerView mYearPickerView;
81bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
82bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private boolean mIsEnabled = true;
83bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
84bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // Accessibility strings.
85bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mDayPickerDescription;
86bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectDay;
87bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mYearPickerDescription;
88bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectYear;
89bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
90bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private AccessibleDateAnimator mAnimator;
91bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
92bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DatePicker.OnDateChangedListener mDateChangedListener;
93bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
94bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int mCurrentView = UNINITIALIZED;
95bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
96bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mCurrentDate;
97bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mTempDate;
98bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mMinDate;
99bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mMaxDate;
100bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1010a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private int mFirstDayOfWeek = USE_LOCALE;
1020a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
103bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
104bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1053053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
106bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
107bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        super(delegator, context);
108bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
109bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final Locale locale = Locale.getDefault();
110bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate = getCalendarForLocale(mMinDate, locale);
111bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate = getCalendarForLocale(mMaxDate, locale);
112bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate = getCalendarForLocale(mMaxDate, locale);
113bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
114bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
115bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.set(DEFAULT_START_YEAR, 1, 1);
116bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.set(DEFAULT_END_YEAR, 12, 31);
117bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
11860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final Resources res = mDelegator.getResources();
119bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final TypedArray a = mContext.obtainStyledAttributes(attrs,
120bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.styleable.DatePicker, defStyleAttr, defStyleRes);
121bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
122bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Context.LAYOUT_INFLATER_SERVICE);
123bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int layoutResourceId = a.getResourceId(
124bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.styleable.DatePicker_internalLayout, R.layout.date_picker_holo);
12560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final View mainView = inflater.inflate(layoutResourceId, null);
126bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.addView(mainView);
127bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
128bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayOfWeekView = (TextView) mainView.findViewById(R.id.date_picker_header);
1297119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
1307119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Layout that contains the current date and day name header.
1317119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final LinearLayout dateLayout = (LinearLayout) mainView.findViewById(
1327119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                R.id.day_picker_selector_layout);
1337119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout = (LinearLayout) mainView.findViewById(
1347119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                R.id.date_picker_month_day_year_layout);
135bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout = (LinearLayout) mainView.findViewById(
136bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.id.date_picker_month_and_day_layout);
137bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setOnClickListener(this);
13860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_month);
13960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_day);
14060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView = (TextView) mainView.findViewById(R.id.date_picker_year);
14160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setOnClickListener(this);
14260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
14360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        // Obtain default highlight color from the theme.
14460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int defaultHighlightColor = mHeaderYearTextView.getHighlightColor();
145bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
146bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Use Theme attributes if possible
14760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int dayOfWeekTextAppearanceResId = a.getResourceId(
14860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_dayOfWeekTextAppearance, -1);
14960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (dayOfWeekTextAppearanceResId != -1) {
15060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mDayOfWeekView.setTextAppearance(context, dayOfWeekTextAppearanceResId);
151bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
152bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
153ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette        mDayOfWeekView.setBackground(a.getDrawable(R.styleable.DatePicker_dayOfWeekBackground));
154ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette
155ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette        dateLayout.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
156bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
15760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int headerSelectedTextColor = a.getColor(
15860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerSelectedTextColor, defaultHighlightColor);
15960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int monthTextAppearanceResId = a.getResourceId(
16060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerMonthTextAppearance, -1);
16160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (monthTextAppearanceResId != -1) {
16260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderMonthTextView.setTextAppearance(context, monthTextAppearanceResId);
163bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
16460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
16560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderMonthTextView.getTextColors(), R.attr.state_selected,
16660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
16760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
16860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int dayOfMonthTextAppearanceResId = a.getResourceId(
16960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerDayOfMonthTextAppearance, -1);
17060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (dayOfMonthTextAppearanceResId != -1) {
17160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderDayOfMonthTextView.setTextAppearance(context, dayOfMonthTextAppearanceResId);
17260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
17360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
17460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderDayOfMonthTextView.getTextColors(), R.attr.state_selected,
17560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
17660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
17760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int yearTextAppearanceResId = a.getResourceId(
17860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerYearTextAppearance, -1);
17960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (yearTextAppearanceResId != -1) {
18060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderYearTextView.setTextAppearance(context, yearTextAppearanceResId);
18160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
18260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setTextColor(ColorStateList.addFirstIfMissing(
18360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderYearTextView.getTextColors(), R.attr.state_selected,
18460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
185bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
186bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerView = new DayPickerView(mContext, this);
18750eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
18850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette
189bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView = new YearPickerView(mContext);
190bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView.init(this);
191bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1927119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int yearSelectedCircleColor = a.getColor(R.styleable.DatePicker_yearListSelectorColor,
1937119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                defaultHighlightColor);
1947119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mYearPickerView.setYearSelectedCircleColor(yearSelectedCircleColor);
1957119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
19660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final ColorStateList calendarTextColor = a.getColorStateList(
19760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarTextColor);
19860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int calendarSelectedTextColor = a.getColor(
19960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarSelectedTextColor, defaultHighlightColor);
20060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mDayPickerView.setCalendarTextColor(ColorStateList.addFirstIfMissing(
20160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                calendarTextColor, R.attr.state_selected, calendarSelectedTextColor));
202bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
203bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerDescription = res.getString(R.string.day_picker_description);
204bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectDay = res.getString(R.string.select_day);
205bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerDescription = res.getString(R.string.year_picker_description);
206bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectYear = res.getString(R.string.select_year);
207bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
208bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
209bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mDayPickerView);
210bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mYearPickerView);
211bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
2127119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2137119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation = new AlphaAnimation(0.0f, 1.0f);
214bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation.setDuration(ANIMATION_DURATION);
215bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setInAnimation(animation);
2167119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2177119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
218bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation2.setDuration(ANIMATION_DURATION);
219bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setOutAnimation(animation2);
220bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
221bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
222bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
223bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
224bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
225bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
226bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Gets a calendar for locale bootstrapped with the value of a given calendar.
227bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
228bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param oldCalendar The old calendar.
229bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param locale The locale.
230bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
231bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
232bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (oldCalendar == null) {
233bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return Calendar.getInstance(locale);
234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
235bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final long currentTimeMillis = oldCalendar.getTimeInMillis();
236bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            Calendar newCalendar = Calendar.getInstance(locale);
237bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            newCalendar.setTimeInMillis(currentTimeMillis);
238bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return newCalendar;
239bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
240bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
241bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
242bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
243bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Compute the array representing the order of Month / Day / Year views in their layout.
244bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Will be used for I18N purpose as the order of them depends on the Locale.
245bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
246bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int[] getMonthDayYearIndexes(String pattern) {
247bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int[] result = new int[3];
248bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
249bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final String filteredPattern = pattern.replaceAll("'.*?'", "");
250bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
251bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int dayIndex = filteredPattern.indexOf('d');
252bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthMIndex = filteredPattern.indexOf("M");
253bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
254bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int yearIndex = filteredPattern.indexOf("y");
255bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
256bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (yearIndex < monthIndex) {
257bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 0;
258bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
259bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
260bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
261bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 2;
262bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
263bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 2;
264bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
265bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
266bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
267bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 2;
268bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
269bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
270bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 0;
271bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
272bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
273bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
274bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 0;
275bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
276bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
277bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return result;
278bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
279bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
280bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updateDisplay(boolean announce) {
281bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mDayOfWeekView != null) {
282bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
283bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    Locale.getDefault()));
284bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
285bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
286bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Compute indices of Month, Day and Year views
2877119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final String bestDateTimePattern =
2887119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
2897119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
290bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
2917119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position the Year and MonthAndDay views within the header.
2927119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout.removeAllViews();
293bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[YEAR_INDEX] == 0) {
2947119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
2957119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
296518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        } else {
2977119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
2987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
299bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
300bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3017119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position Day and Month views within the MonthAndDay view.
3027119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthAndDayLayout.removeAllViews();
303bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
30460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
30560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
306bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
30760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
30860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
309bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
310bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
31160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
312bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Locale.getDefault()).toUpperCase(Locale.getDefault()));
31360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
31460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
315bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
316bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Accessibility.
317bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
318bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(millis);
319bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
320bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
321bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setContentDescription(monthAndDayText);
322bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
323bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (announce) {
324bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
325bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
326bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mAnimator.announceForAccessibility(fullDateText);
327bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
328bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
329bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void setCurrentView(final int viewIndex) {
332bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
334bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (viewIndex) {
335bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case MONTH_AND_DAY_VIEW:
336bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.onDateChanged();
337bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
338bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(true);
33960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(false);
340bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
341bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
342bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
343bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3447119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final int flags = DateUtils.FORMAT_SHOW_DATE;
3457119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
346bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
347bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectDay);
348bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
349bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case YEAR_VIEW:
350bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.onDateChanged();
351bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
352bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(false);
35360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(true);
354bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(YEAR_VIEW);
355bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
356bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
357bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3587119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final CharSequence yearString = mYearFormat.format(millis);
359bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
360bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectYear);
361bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
362bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
363bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
364bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
365bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
367bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            DatePicker.OnDateChangedListener callBack) {
368bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDateChangedListener = callBack;
369bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
370bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
3809468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        if (mDateChangedListener != null) {
3819468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
3829468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
383bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
384bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
385bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
386bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
387bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
390bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
391bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
392bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
393bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
394bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
395bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
396bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
397bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
398bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
399bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
400bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
401bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
402bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
403bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
404bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
405bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
406bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
407bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
408bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
410bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
411bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
41450eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
41550eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
43650eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
43750eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
439bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4460a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4470a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
4480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4530a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
455bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
456bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
459bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setEnabled(enabled);
46160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setEnabled(enabled);
462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setEnabled(enabled);
463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mIsEnabled = enabled;
464bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
465bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
468bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mIsEnabled;
469bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        throw new UnsupportedOperationException(
474bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                "CalendarView does not exists for the new DatePicker");
475bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
476bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
477bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
478bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
479bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
483bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
484bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
485bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
492bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
493bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentView == MONTH_AND_DAY_VIEW) {
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (mCurrentView == YEAR_VIEW) {
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        SavedState ss = (SavedState) state;
526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
527a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentView = ss.getCurrentView();
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(mCurrentView);
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (mCurrentView == MONTH_AND_DAY_VIEW) {
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.postSetSelection(listPosition);
539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else if (mCurrentView == YEAR_VIEW) {
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
554bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
555bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
556bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
557bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
558bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.setClassName(DatePicker.class.getName());
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        info.setClassName(DatePicker.class.getName());
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onYearSelected(int year) {
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(true);
573bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
574bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // If the newly selected month / year does not contain the currently selected day number,
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // change the selected day number to the last day of the selected month or year.
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void adjustDayInMonthIfNeeded(int month, int year) {
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int daysInMonth = getDaysInMonth(month, year);
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (day > daysInMonth) {
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
596bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onDayOfMonthSelected(int year, int month, int day) {
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, day);
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(true);
616bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updatePickers() {
61960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        for (OnDateChangedListener listener : mListeners) {
62060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            listener.onDateChanged();
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void registerOnDateChangedListener(OnDateChangedListener listener) {
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.add(listener);
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void unregisterOnDateChangedListener(OnDateChangedListener listener) {
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.remove(listener);
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getSelectedDay() {
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate;
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void tryVibrate() {
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onClick(View v) {
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        tryVibrate();
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (v.getId() == R.id.date_picker_year) {
648bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(YEAR_VIEW);
649bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
650bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(MONTH_AND_DAY_VIEW);
651bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
652bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
653bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
654bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
655bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
656bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
657bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
658bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
659bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
660bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
661bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
662bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
663bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
664bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
665bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
666bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
667bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
668bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
669bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
670bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
671bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
672bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
707bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
708bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
709bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
710bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
711bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
712bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
713bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
714bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
715bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
716bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
717bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
718bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
719bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
720bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
721bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
722bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
723bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
724bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
725bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
726bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
727bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
728bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
729bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
730bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
731bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
732bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
733bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
734bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
735bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
736bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
737bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
738bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
739bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
740bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
741bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
742bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
743bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
744bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
745bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
746bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
747bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
748bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
749bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
750bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
751bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
752bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
753bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
754bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
755bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
756bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
757bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
758bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
759