DatePickerCalendarDelegate.java revision a7bb6fbeab933326d58aa806d8194b7b13239d34
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(
1484e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_dayOfWeekTextAppearance, 0);
1494e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        if (dayOfWeekTextAppearanceResId != 0) {
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(
1604e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_headerMonthTextAppearance, 0);
1614e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        if (monthTextAppearanceResId != 0) {
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(
1694e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_headerDayOfMonthTextAppearance, 0);
1704e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        if (dayOfMonthTextAppearanceResId != 0) {
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
1774e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        final int headerYearTextAppearanceResId = a.getResourceId(
1784e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_headerYearTextAppearance, 0);
1794e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        if (headerYearTextAppearanceResId != 0) {
1804e5168fae43e783a35c5bc731e500196005268fbAlan Viverette            mHeaderYearTextView.setTextAppearance(context, headerYearTextAppearanceResId);
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
1964e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        final ColorStateList yearBackgroundColor = a.getColorStateList(
1974e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_yearListSelectorColor);
1984e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        mYearPickerView.setYearBackgroundColor(yearBackgroundColor);
1994e5168fae43e783a35c5bc731e500196005268fbAlan Viverette
2004e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        final int yearTextAppearanceResId = a.getResourceId(
2014e5168fae43e783a35c5bc731e500196005268fbAlan Viverette                R.styleable.DatePicker_yearListItemTextAppearance, 0);
2024e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        if (yearTextAppearanceResId != 0) {
2034e5168fae43e783a35c5bc731e500196005268fbAlan Viverette            mYearPickerView.setYearTextAppearance(yearTextAppearanceResId);
2044e5168fae43e783a35c5bc731e500196005268fbAlan Viverette        }
2057119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
20660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final ColorStateList calendarTextColor = a.getColorStateList(
20760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarTextColor);
208c5b95c20b6fd3f4e63147efb22dd19c657b17001Alan Viverette        mDayPickerView.setCalendarTextColor(calendarTextColor);
209c5b95c20b6fd3f4e63147efb22dd19c657b17001Alan Viverette
210c5b95c20b6fd3f4e63147efb22dd19c657b17001Alan Viverette        final ColorStateList calendarDayBackgroundColor = a.getColorStateList(
211c5b95c20b6fd3f4e63147efb22dd19c657b17001Alan Viverette                R.styleable.DatePicker_calendarDayBackgroundColor);
212c5b95c20b6fd3f4e63147efb22dd19c657b17001Alan Viverette        mDayPickerView.setCalendarDayBackgroundColor(calendarDayBackgroundColor);
213bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
214bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerDescription = res.getString(R.string.day_picker_description);
215bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectDay = res.getString(R.string.select_day);
216bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerDescription = res.getString(R.string.year_picker_description);
217bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectYear = res.getString(R.string.select_year);
218bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
219bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
220bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mDayPickerView);
221bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mYearPickerView);
222bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
2237119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2247119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation = new AlphaAnimation(0.0f, 1.0f);
225bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation.setDuration(ANIMATION_DURATION);
226bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setInAnimation(animation);
2277119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2287119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
229bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation2.setDuration(ANIMATION_DURATION);
230bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setOutAnimation(animation2);
231bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
232bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
233bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
235bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
236bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
237bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Gets a calendar for locale bootstrapped with the value of a given calendar.
238bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
239bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param oldCalendar The old calendar.
240bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param locale The locale.
241bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
242bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
243bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (oldCalendar == null) {
244bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return Calendar.getInstance(locale);
245bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
246bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final long currentTimeMillis = oldCalendar.getTimeInMillis();
247bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            Calendar newCalendar = Calendar.getInstance(locale);
248bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            newCalendar.setTimeInMillis(currentTimeMillis);
249bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return newCalendar;
250bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
251bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
252bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
253bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
254bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Compute the array representing the order of Month / Day / Year views in their layout.
255bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Will be used for I18N purpose as the order of them depends on the Locale.
256bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
257bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int[] getMonthDayYearIndexes(String pattern) {
258bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int[] result = new int[3];
259bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
260bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final String filteredPattern = pattern.replaceAll("'.*?'", "");
261bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
262bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int dayIndex = filteredPattern.indexOf('d');
263bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthMIndex = filteredPattern.indexOf("M");
264bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
265bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int yearIndex = filteredPattern.indexOf("y");
266bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
267bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (yearIndex < monthIndex) {
268bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 0;
269bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
270bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
271bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
272bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 2;
273bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
274bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 2;
275bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
276bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
277bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
278bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 2;
279bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
280bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
281bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 0;
282bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
283bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
284bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
285bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 0;
286bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
287bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
288bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return result;
289bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
290bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
291bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updateDisplay(boolean announce) {
292bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mDayOfWeekView != null) {
293bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
294bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    Locale.getDefault()));
295bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
296bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
297bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Compute indices of Month, Day and Year views
2987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final String bestDateTimePattern =
2997119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
3007119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
301bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3027119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position the Year and MonthAndDay views within the header.
3037119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout.removeAllViews();
304bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[YEAR_INDEX] == 0) {
3057119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
3067119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
307518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        } else {
3087119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
3097119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
310bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
311bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3127119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position Day and Month views within the MonthAndDay view.
3137119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthAndDayLayout.removeAllViews();
314bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
31560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
31660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
317bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
31860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
31960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
320bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
321bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
32260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
323bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Locale.getDefault()).toUpperCase(Locale.getDefault()));
32460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
32560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
326bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
327bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Accessibility.
328bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
329bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(millis);
330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
332bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setContentDescription(monthAndDayText);
333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
334bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (announce) {
335bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
336bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
337bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mAnimator.announceForAccessibility(fullDateText);
338bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
339bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
340bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
341bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void setCurrentView(final int viewIndex) {
342bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
343bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
344bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (viewIndex) {
345bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case MONTH_AND_DAY_VIEW:
3464612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette                mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
347bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
348bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(true);
34960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(false);
350bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
351bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
352bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
353bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3547119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final int flags = DateUtils.FORMAT_SHOW_DATE;
3557119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
356bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
357bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectDay);
358bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
359bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case YEAR_VIEW:
360bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.onDateChanged();
361bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                if (mCurrentView != viewIndex) {
362bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mMonthAndDayLayout.setSelected(false);
36360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                    mHeaderYearTextView.setSelected(true);
364bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mAnimator.setDisplayedChild(YEAR_VIEW);
365bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    mCurrentView = viewIndex;
366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                }
367bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3687119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                final CharSequence yearString = mYearFormat.format(millis);
369bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
370bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mAnimator.announceForAccessibility(mSelectYear);
371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                break;
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void init(int year, int monthOfYear, int dayOfMonth,
377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            DatePicker.OnDateChangedListener callBack) {
378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
380bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
381e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
382e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        mDateChangedListener = callBack;
3830cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette
3840cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, false);
385bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
386bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
387bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
390bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
391bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
392e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3930cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(false, true);
394e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette    }
395e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
3960cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette    private void onDateChanged(boolean fromUser, boolean callbackToClient) {
3970cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        if (callbackToClient && mDateChangedListener != null) {
398e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int year = mCurrentDate.get(Calendar.YEAR);
399e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
400e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
401e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
402e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        }
403e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
404e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        for (OnDateChangedListener listener : mListeners) {
405e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            listener.onDateChanged();
406e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        }
407e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
408e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
409e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
410e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        updateDisplay(fromUser);
411e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
412e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        if (fromUser) {
413e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette            tryVibrate();
4149468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
439bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
4410cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
4444612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMinDate(minDate);
44550eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
446bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
448bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
449bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
450bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
452bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
453bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
454bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
455bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
456bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
459bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
461bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
4620cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(false, true);
463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
464bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
4654612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette        mDayPickerView.setMaxDate(maxDate);
46650eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
468bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
469bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
474bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4750a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4760a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
477e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
478e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
4790a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4800a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4810a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4830a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4840a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4850a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setEnabled(enabled);
49260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setEnabled(enabled);
493bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setEnabled(enabled);
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mIsEnabled = enabled;
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mIsEnabled;
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        throw new UnsupportedOperationException(
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                "CalendarView does not exists for the new DatePicker");
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentView == MONTH_AND_DAY_VIEW) {
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (mCurrentView == YEAR_VIEW) {
546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
554bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
555bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
556bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        SavedState ss = (SavedState) state;
557bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
558a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentView = ss.getCurrentView();
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(mCurrentView);
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (mCurrentView == MONTH_AND_DAY_VIEW) {
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.postSetSelection(listPosition);
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else if (mCurrentView == YEAR_VIEW) {
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
573bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
574bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
587a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn    public CharSequence getAccessibilityClassName() {
588a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn        return DatePicker.class.getName();
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onYearSelected(int year) {
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
5950cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette        onDateChanged(true, true);
596e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette
597e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette        // Auto-advance to month and day view.
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // If the newly selected month / year does not contain the currently selected day number,
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // change the selected day number to the last day of the selected month or year.
603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void adjustDayInMonthIfNeeded(int month, int year) {
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int daysInMonth = getDaysInMonth(month, year);
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (day > daysInMonth) {
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
616bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
619bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
620bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void registerOnDateChangedListener(OnDateChangedListener listener) {
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.add(listener);
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getSelectedDay() {
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate;
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void tryVibrate() {
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
648bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
649bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
650bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
651bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onClick(View v) {
652bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        tryVibrate();
653bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (v.getId() == R.id.date_picker_year) {
654bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(YEAR_VIEW);
655bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
656bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(MONTH_AND_DAY_VIEW);
657bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
658bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
659bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
660bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
661e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     * Listener called when the user selects a day in the day picker view.
662e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     */
663e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    private final DayPickerView.OnDaySelectedListener
664e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mOnDaySelectedListener = new DayPickerView.OnDaySelectedListener() {
665e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        @Override
666e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        public void onDaySelected(DayPickerView view, Calendar day) {
667e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
6680cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette            onDateChanged(true, true);
669e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        }
670e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    };
671e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
672e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    /**
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
707bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
708bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
709bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
710bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
711bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
712bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
713bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
714bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
715bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
716bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
717bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
718bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
719bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
720bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
721bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
722bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
723bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
724bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
725bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
726bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
727bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
728bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
729bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
730bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
731bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
732bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
733bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
734bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
735bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
736bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
737bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
738bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
739bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
740bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
741bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
742bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
743bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
744bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
745bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
746bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
747bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
748bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
749bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
750bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
751bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
752bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
753bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
754bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
755bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
756bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
757bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
758bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
759bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
760bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
761bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
762bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
763bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
764bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
765bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
766bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
767bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
768bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
769bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
770bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
771bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
772bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
773bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
774bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
775bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
776bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
777