DatePickerCalendarDelegate.java revision 0cecbc9c7208f918ddf9d117057649f6e132069f
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
186e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView = new DayPickerView(mContext);
187e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
1884612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
1894612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
1904612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
191e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
19250eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette
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    }
333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
334bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void setCurrentView(final int viewIndex) {
335bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
336bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
337bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (viewIndex) {
338bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case MONTH_AND_DAY_VIEW:
3394612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette                mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
340bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
341bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(true);
34260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(false);
343bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
344bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
345bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
346bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3477119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final int flags = DateUtils.FORMAT_SHOW_DATE;
3487119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
349bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
350bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectDay);
351bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
352bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case YEAR_VIEW:
353bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.onDateChanged();
354bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
355bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(false);
35660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(true);
357bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(YEAR_VIEW);
358bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
359bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
360bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3617119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final CharSequence yearString = mYearFormat.format(millis);
362bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
363bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectYear);
364bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
365bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
367bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
368bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
369bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
370bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            DatePicker.OnDateChangedListener callBack) {
371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
374e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
375e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        mDateChangedListener = callBack;
3760cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette
3770cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, false);
378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
380bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
381bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
382bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
383bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
384bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
385e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3860cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, true);
387e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette    }
388e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3890cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette    private void onDateChanged(boolean fromUser, boolean callbackToClient) {
3900cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        if (callbackToClient && mDateChangedListener != null) {
391e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int year = mCurrentDate.get(Calendar.YEAR);
392e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
393e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
394e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
395e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        }
396e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
397e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        for (OnDateChangedListener listener : mListeners) {
398e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            listener.onDateChanged();
399e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        }
400e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
401e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
402e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
403e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        updateDisplay(fromUser);
404e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
405e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        if (fromUser) {
406e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            tryVibrate();
4079468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
408bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
410bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
411bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
414bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
4340cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
4374612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMinDate(minDate);
43850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
439bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
446bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
448bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
449bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
450bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
452bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
453bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
454bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
4550cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
456bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
4584612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMaxDate(maxDate);
45950eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
461bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
464bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
465bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4680a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4690a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
470e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
471e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
4720a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4730a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4740a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
475bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4760a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4770a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4780a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
479bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
483bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
484bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setEnabled(enabled);
48560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setEnabled(enabled);
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setEnabled(enabled);
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mIsEnabled = enabled;
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
492bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mIsEnabled;
493bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        throw new UnsupportedOperationException(
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                "CalendarView does not exists for the new DatePicker");
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentView == MONTH_AND_DAY_VIEW) {
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (mCurrentView == YEAR_VIEW) {
539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        SavedState ss = (SavedState) state;
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
551a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentView = ss.getCurrentView();
553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
554bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
555bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
556bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
557bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(mCurrentView);
558bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (mCurrentView == MONTH_AND_DAY_VIEW) {
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.postSetSelection(listPosition);
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else if (mCurrentView == YEAR_VIEW) {
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
573bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
574bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.setClassName(DatePicker.class.getName());
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        info.setClassName(DatePicker.class.getName());
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onYearSelected(int year) {
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
5940cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(true, true);
595e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
596e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        // Auto-advance to month and day view.
597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // If the newly selected month / year does not contain the currently selected day number,
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // change the selected day number to the last day of the selected month or year.
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void adjustDayInMonthIfNeeded(int month, int year) {
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int daysInMonth = getDaysInMonth(month, year);
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (day > daysInMonth) {
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
616bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
619bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
620bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void registerOnDateChangedListener(OnDateChangedListener listener) {
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.add(listener);
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getSelectedDay() {
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate;
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void tryVibrate() {
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
648bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
649bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
650bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onClick(View v) {
651bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        tryVibrate();
652bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (v.getId() == R.id.date_picker_year) {
653bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(YEAR_VIEW);
654bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
655bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(MONTH_AND_DAY_VIEW);
656bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
657bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
658bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
659bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
660e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     * Listener called when the user selects a day in the day picker view.
661e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     */
662e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    private final DayPickerView.OnDaySelectedListener
663e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mOnDaySelectedListener = new DayPickerView.OnDaySelectedListener() {
664e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        @Override
665e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        public void onDaySelected(DayPickerView view, Calendar day) {
666e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
6670cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(true, true);
668e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        }
669e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    };
670e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
671e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    /**
672bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
707bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
708bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
709bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
710bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
711bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
712bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
713bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
714bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
715bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
716bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
717bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
718bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
719bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
720bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
721bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
722bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
723bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
724bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
725bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
726bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
727bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
728bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
729bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
730bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
731bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
732bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
733bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
734bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
735bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
736bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
737bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
738bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
739bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
740bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
741bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
742bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
743bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
744bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
745bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
746bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
747bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
748bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
749bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
750bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
751bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
752bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
753bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
754bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
755bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
756bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
757bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
758bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
759bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
760bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
761bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
762bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
763bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
764bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
765bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
766bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
767bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
768bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
769bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
770bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
771bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
772bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
773bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
774bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
775bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
776