DatePickerCalendarDelegate.java revision 0a04bb0d4bf18318fe5473bf5615c2016bc26373
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;
2460727e07c6ef72e2f494266939c02494a3df28f8Alan Viveretteimport android.graphics.Color;
25bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcel;
26bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcelable;
27bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateFormat;
28bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateUtils;
29bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.util.AttributeSet;
30bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.util.SparseArray;
31bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.HapticFeedbackConstants;
32bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.LayoutInflater;
33bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.View;
34bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityEvent;
35bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityNodeInfo;
36bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.animation.AlphaAnimation;
37bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.animation.Animation;
38bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
39bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport com.android.internal.R;
40bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport com.android.internal.widget.AccessibleDateAnimator;
41bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
42bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.text.SimpleDateFormat;
43bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Calendar;
44bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.HashSet;
45bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Locale;
46bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
47bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/**
48bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * A delegate for picking up a date (day / month / year).
49bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */
503053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haaseclass DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate implements
51bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        View.OnClickListener, DatePickerController {
520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private static final int USE_LOCALE = 0;
53bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
54bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int UNINITIALIZED = -1;
55bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int MONTH_AND_DAY_VIEW = 0;
56bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int YEAR_VIEW = 1;
57bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
58bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_START_YEAR = 1900;
59bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DEFAULT_END_YEAR = 2100;
60bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
61bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int ANIMATION_DURATION = 300;
62bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
63bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int MONTH_INDEX = 0;
64bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int DAY_INDEX = 1;
65bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static final int YEAR_INDEX = 2;
66bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
67bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private SimpleDateFormat mYearFormat = new SimpleDateFormat("y", Locale.getDefault());
68bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private SimpleDateFormat mDayFormat = new SimpleDateFormat("d", Locale.getDefault());
69bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
70bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private TextView mDayOfWeekView;
717119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
727119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    /** Layout that contains the current month, day, and year. */
737119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    private LinearLayout mMonthDayYearLayout;
747119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
757119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette    /** Clickable layout that contains the current day and year. */
76bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private LinearLayout mMonthAndDayLayout;
777119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
7860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderMonthTextView;
7960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderDayOfMonthTextView;
8060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette    private TextView mHeaderYearTextView;
81bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DayPickerView mDayPickerView;
82bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private YearPickerView mYearPickerView;
83bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
84bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private boolean mIsEnabled = true;
85bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
86bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // Accessibility strings.
87bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mDayPickerDescription;
88bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectDay;
89bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mYearPickerDescription;
90bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private String mSelectYear;
91bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
92bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private AccessibleDateAnimator mAnimator;
93bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
94bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private DatePicker.OnDateChangedListener mDateChangedListener;
95bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
96bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int mCurrentView = UNINITIALIZED;
97bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
98bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mCurrentDate;
99bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mTempDate;
100bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mMinDate;
101bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar mMaxDate;
102bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1030a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    private int mFirstDayOfWeek = USE_LOCALE;
1040a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
105bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
106bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1073053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase    public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
108bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            int defStyleAttr, int defStyleRes) {
109bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        super(delegator, context);
110bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
111bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final Locale locale = Locale.getDefault();
112bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate = getCalendarForLocale(mMinDate, locale);
113bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate = getCalendarForLocale(mMaxDate, locale);
114bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate = getCalendarForLocale(mMaxDate, locale);
115bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
116bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
117bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.set(DEFAULT_START_YEAR, 1, 1);
118bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.set(DEFAULT_END_YEAR, 12, 31);
119bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
12060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final Resources res = mDelegator.getResources();
121bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final TypedArray a = mContext.obtainStyledAttributes(attrs,
122bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.styleable.DatePicker, defStyleAttr, defStyleRes);
123bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
124bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Context.LAYOUT_INFLATER_SERVICE);
125bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int layoutResourceId = a.getResourceId(
126bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.styleable.DatePicker_internalLayout, R.layout.date_picker_holo);
12760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final View mainView = inflater.inflate(layoutResourceId, null);
128bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.addView(mainView);
129bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
130bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayOfWeekView = (TextView) mainView.findViewById(R.id.date_picker_header);
1317119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
1327119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Layout that contains the current date and day name header.
1337119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final LinearLayout dateLayout = (LinearLayout) mainView.findViewById(
1347119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                R.id.day_picker_selector_layout);
1357119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout = (LinearLayout) mainView.findViewById(
1367119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                R.id.date_picker_month_day_year_layout);
137bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout = (LinearLayout) mainView.findViewById(
138bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                R.id.date_picker_month_and_day_layout);
139bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setOnClickListener(this);
14060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_month);
14160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_day);
14260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView = (TextView) mainView.findViewById(R.id.date_picker_year);
14360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setOnClickListener(this);
14460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
14560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        // Obtain default highlight color from the theme.
14660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int defaultHighlightColor = mHeaderYearTextView.getHighlightColor();
147bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
148bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Use Theme attributes if possible
14960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int dayOfWeekTextAppearanceResId = a.getResourceId(
15060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_dayOfWeekTextAppearance, -1);
15160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (dayOfWeekTextAppearanceResId != -1) {
15260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mDayOfWeekView.setTextAppearance(context, dayOfWeekTextAppearanceResId);
153bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
154bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
15560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int dayOfWeekBackgroundColor = a.getColor(
15660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_dayOfWeekBackgroundColor, Color.TRANSPARENT);
15760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mDayOfWeekView.setBackgroundColor(dayOfWeekBackgroundColor);
158bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
15960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int headerSelectedTextColor = a.getColor(
16060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerSelectedTextColor, defaultHighlightColor);
16160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int headerBackgroundColor = a.getColor(R.styleable.DatePicker_headerBackgroundColor,
16260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                Color.TRANSPARENT);
1637119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        dateLayout.setBackgroundColor(headerBackgroundColor);
164bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
16560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int monthTextAppearanceResId = a.getResourceId(
16660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerMonthTextAppearance, -1);
16760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (monthTextAppearanceResId != -1) {
16860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderMonthTextView.setTextAppearance(context, monthTextAppearanceResId);
169bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
17060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
17160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderMonthTextView.getTextColors(), R.attr.state_selected,
17260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
17360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
17460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int dayOfMonthTextAppearanceResId = a.getResourceId(
17560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerDayOfMonthTextAppearance, -1);
17660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (dayOfMonthTextAppearanceResId != -1) {
17760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderDayOfMonthTextView.setTextAppearance(context, dayOfMonthTextAppearanceResId);
17860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
17960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setTextColor(ColorStateList.addFirstIfMissing(
18060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderDayOfMonthTextView.getTextColors(), R.attr.state_selected,
18160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
18260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette
18360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int yearTextAppearanceResId = a.getResourceId(
18460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_headerYearTextAppearance, -1);
18560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        if (yearTextAppearanceResId != -1) {
18660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mHeaderYearTextView.setTextAppearance(context, yearTextAppearanceResId);
18760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        }
18860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setTextColor(ColorStateList.addFirstIfMissing(
18960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                mHeaderYearTextView.getTextColors(), R.attr.state_selected,
19060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                headerSelectedTextColor));
191bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
192bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerView = new DayPickerView(mContext, this);
193bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView = new YearPickerView(mContext);
194bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView.init(this);
195bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1967119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int yearSelectedCircleColor = a.getColor(R.styleable.DatePicker_yearListSelectorColor,
1977119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                defaultHighlightColor);
1987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mYearPickerView.setYearSelectedCircleColor(yearSelectedCircleColor);
1997119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
20060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final ColorStateList calendarTextColor = a.getColorStateList(
20160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarTextColor);
20260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int calendarSelectedTextColor = a.getColor(
20360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarSelectedTextColor, defaultHighlightColor);
20460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mDayPickerView.setCalendarTextColor(ColorStateList.addFirstIfMissing(
20560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                calendarTextColor, R.attr.state_selected, calendarSelectedTextColor));
206bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
207bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerDescription = res.getString(R.string.day_picker_description);
208bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectDay = res.getString(R.string.select_day);
209bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerDescription = res.getString(R.string.year_picker_description);
210bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectYear = res.getString(R.string.select_year);
211bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
212bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
213bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mDayPickerView);
214bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mYearPickerView);
215bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
2167119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2177119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation = new AlphaAnimation(0.0f, 1.0f);
218bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation.setDuration(ANIMATION_DURATION);
219bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setInAnimation(animation);
2207119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2217119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
222bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation2.setDuration(ANIMATION_DURATION);
223bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setOutAnimation(animation2);
224bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
225bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
226bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
227bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
228bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
229bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
230bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Gets a calendar for locale bootstrapped with the value of a given calendar.
231bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
232bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param oldCalendar The old calendar.
233bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param locale The locale.
234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
235bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
236bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (oldCalendar == null) {
237bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return Calendar.getInstance(locale);
238bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
239bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final long currentTimeMillis = oldCalendar.getTimeInMillis();
240bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            Calendar newCalendar = Calendar.getInstance(locale);
241bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            newCalendar.setTimeInMillis(currentTimeMillis);
242bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return newCalendar;
243bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
244bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
245bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
246bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
247bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Compute the array representing the order of Month / Day / Year views in their layout.
248bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Will be used for I18N purpose as the order of them depends on the Locale.
249bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
250bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int[] getMonthDayYearIndexes(String pattern) {
251bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int[] result = new int[3];
252bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
253bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final String filteredPattern = pattern.replaceAll("'.*?'", "");
254bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
255bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int dayIndex = filteredPattern.indexOf('d');
256bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthMIndex = filteredPattern.indexOf("M");
257bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
258bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int yearIndex = filteredPattern.indexOf("y");
259bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
260bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (yearIndex < monthIndex) {
261bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 0;
262bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
263bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
264bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
265bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 2;
266bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
267bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 2;
268bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
269bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
270bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
271bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 2;
272bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
273bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
274bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 0;
275bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
276bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
277bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
278bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 0;
279bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
280bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
281bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return result;
282bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
283bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
284bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updateDisplay(boolean announce) {
285bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mDayOfWeekView != null) {
286bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
287bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    Locale.getDefault()));
288bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
289bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
290bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Compute indices of Month, Day and Year views
2917119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final String bestDateTimePattern =
2927119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
2937119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
294bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
2957119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position the Year and MonthAndDay views within the header.
2967119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout.removeAllViews();
297bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[YEAR_INDEX] == 0) {
2987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
2997119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
300518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        } else {
3017119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
3027119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
303bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
304bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3057119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position Day and Month views within the MonthAndDay view.
3067119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthAndDayLayout.removeAllViews();
307bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
30860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
30960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
310bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
31160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
31260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
313bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
314bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
31560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
316bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Locale.getDefault()).toUpperCase(Locale.getDefault()));
31760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
31860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
319bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
320bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Accessibility.
321bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
322bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(millis);
323bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
324bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
325bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setContentDescription(monthAndDayText);
326bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
327bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (announce) {
328bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
329bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mAnimator.announceForAccessibility(fullDateText);
331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
332bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
334bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
335bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void setCurrentView(final int viewIndex) {
336bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
337bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
338bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (viewIndex) {
339bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case MONTH_AND_DAY_VIEW:
340bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.onDateChanged();
341bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
342bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(true);
34360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(false);
344bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
345bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
346bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
347bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3487119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final int flags = DateUtils.FORMAT_SHOW_DATE;
3497119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
350bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
351bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectDay);
352bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
353bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case YEAR_VIEW:
354bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.onDateChanged();
355bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
356bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(false);
35760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(true);
358bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(YEAR_VIEW);
359bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
360bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
361bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3627119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final CharSequence yearString = mYearFormat.format(millis);
363bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
364bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectYear);
365bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
367bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
368bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
369bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
370bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            DatePicker.OnDateChangedListener callBack) {
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDateChangedListener = callBack;
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
380bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
381bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
382bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
383bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
3849468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        if (mDateChangedListener != null) {
3859468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
3869468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
387bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
390bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
391bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
392bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
393bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
394bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
395bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
396bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
397bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
398bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
399bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
400bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
401bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
402bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
403bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
404bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
405bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
406bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
407bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
408bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
410bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
411bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
414bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerView.goTo(getSelectedDay(), false, true, true);
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
439bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerView.goTo(getSelectedDay(), false, true, true);
440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
446bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4480a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
4500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4510a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4520a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
453bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4550a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4560a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
459bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
461bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMinYear() {
462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate.get(Calendar.YEAR);
463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
464bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
465bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMaxYear() {
467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate.get(Calendar.YEAR);
468bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
469bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMinMonth() {
472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate.get(Calendar.MONTH);
473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
474bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
475bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
476bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMaxMonth() {
477bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate.get(Calendar.MONTH);
478bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
479bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMinDay() {
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate.get(Calendar.DAY_OF_MONTH);
483bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
484bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
485bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMaxDay() {
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate.get(Calendar.DAY_OF_MONTH);
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
492bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setEnabled(enabled);
49360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setEnabled(enabled);
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setEnabled(enabled);
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mIsEnabled = enabled;
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mIsEnabled;
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        throw new UnsupportedOperationException(
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                "CalendarView does not exists for the new DatePicker");
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Nothing to do
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentView == MONTH_AND_DAY_VIEW) {
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (mCurrentView == YEAR_VIEW) {
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
554bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
555bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
556bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
557bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
558bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        SavedState ss = (SavedState) state;
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(ss.getSelectedDay(), ss.getSelectedMonth(), ss.getSelectedYear());
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentView = ss.getCurrentView();
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(mCurrentView);
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
573bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
574bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (mCurrentView == MONTH_AND_DAY_VIEW) {
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.postSetSelection(listPosition);
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else if (mCurrentView == YEAR_VIEW) {
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.setClassName(DatePicker.class.getName());
596bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        info.setClassName(DatePicker.class.getName());
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onYearSelected(int year) {
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(true);
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // If the newly selected month / year does not contain the currently selected day number,
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // change the selected day number to the last day of the selected month or year.
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
616bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void adjustDayInMonthIfNeeded(int month, int year) {
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int daysInMonth = getDaysInMonth(month, year);
619bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (day > daysInMonth) {
620bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onDayOfMonthSelected(int year, int month, int day) {
648bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
649bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
650bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, day);
651bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
652bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(true);
653bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
654bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
655bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updatePickers() {
65660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        for (OnDateChangedListener listener : mListeners) {
65760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            listener.onDateChanged();
658bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
659bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
660bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
661bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
662bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void registerOnDateChangedListener(OnDateChangedListener listener) {
663bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.add(listener);
664bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
665bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
666bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
667bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void unregisterOnDateChangedListener(OnDateChangedListener listener) {
668bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.remove(listener);
669bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
670bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
671bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
672bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getSelectedDay() {
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate;
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void tryVibrate() {
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onClick(View v) {
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        tryVibrate();
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (v.getId() == R.id.date_picker_year) {
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(YEAR_VIEW);
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(MONTH_AND_DAY_VIEW);
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
707bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
708bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
709bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
710bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
711bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
712bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
713bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
714bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
715bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
716bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
717bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
718bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
719bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
720bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
721bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
722bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
723bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
724bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
725bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
726bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
727bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
728bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
729bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
730bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
731bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
732bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
733bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
734bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
735bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
736bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
737bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
738bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
739bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
740bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
741bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
742bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
743bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
744bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
745bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
746bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
747bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
748bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
749bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
750bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
751bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
752bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
753bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
754bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
755bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
756bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
757bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
758bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
759bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
760bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
761bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
762bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
763bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
764bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
765bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
766bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
767bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
768bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
769bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
770bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
771bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
772bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
773bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
774bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
775bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
776bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
777bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
778bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
779bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
780bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
781bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
782bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
783bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
784bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
785bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
786bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
787bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
788bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
789bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
790bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
791bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
792bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
793bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
794bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
795bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
796