DatePickerCalendarDelegate.java revision e763c9bd6ed0ca46daafc21fc4313ebcad4bcafa
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);
18850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
189e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setDay(mCurrentDate);
190e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
19150eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette
192bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView = new YearPickerView(mContext);
193bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerView.init(this);
194bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
1957119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int yearSelectedCircleColor = a.getColor(R.styleable.DatePicker_yearListSelectorColor,
1967119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                defaultHighlightColor);
1977119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mYearPickerView.setYearSelectedCircleColor(yearSelectedCircleColor);
1987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
19960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final ColorStateList calendarTextColor = a.getColorStateList(
20060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarTextColor);
20160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        final int calendarSelectedTextColor = a.getColor(
20260727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                R.styleable.DatePicker_calendarSelectedTextColor, defaultHighlightColor);
20360727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mDayPickerView.setCalendarTextColor(ColorStateList.addFirstIfMissing(
20460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette                calendarTextColor, R.attr.state_selected, calendarSelectedTextColor));
205bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
206bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayPickerDescription = res.getString(R.string.day_picker_description);
207bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectDay = res.getString(R.string.select_day);
208bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearPickerDescription = res.getString(R.string.year_picker_description);
209bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mSelectYear = res.getString(R.string.select_year);
210bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
211bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
212bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mDayPickerView);
213bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.addView(mYearPickerView);
214bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
2157119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2167119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation = new AlphaAnimation(0.0f, 1.0f);
217bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation.setDuration(ANIMATION_DURATION);
218bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setInAnimation(animation);
2197119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette
2207119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
221bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        animation2.setDuration(ANIMATION_DURATION);
222bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setOutAnimation(animation2);
223bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
224bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
225bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
226bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
227bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
228bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
229bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Gets a calendar for locale bootstrapped with the value of a given calendar.
230bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     *
231bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param oldCalendar The old calendar.
232bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * @param locale The locale.
233bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
235bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (oldCalendar == null) {
236bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return Calendar.getInstance(locale);
237bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
238bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            final long currentTimeMillis = oldCalendar.getTimeInMillis();
239bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            Calendar newCalendar = Calendar.getInstance(locale);
240bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            newCalendar.setTimeInMillis(currentTimeMillis);
241bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return newCalendar;
242bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
243bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
244bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
245bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
246bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Compute the array representing the order of Month / Day / Year views in their layout.
247bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Will be used for I18N purpose as the order of them depends on the Locale.
248bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
249bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private int[] getMonthDayYearIndexes(String pattern) {
250bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int[] result = new int[3];
251bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
252bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final String filteredPattern = pattern.replaceAll("'.*?'", "");
253bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
254bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int dayIndex = filteredPattern.indexOf('d');
255bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthMIndex = filteredPattern.indexOf("M");
256bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
257bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int yearIndex = filteredPattern.indexOf("y");
258bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
259bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (yearIndex < monthIndex) {
260bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 0;
261bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
262bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
263bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
264bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 2;
265bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
266bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 2;
267bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
268bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
269bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
270bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            result[YEAR_INDEX] = 2;
271bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
272bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (monthIndex < dayIndex) {
273bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 0;
274bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 1;
275bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else {
276bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[MONTH_INDEX] = 1;
277bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                result[DAY_INDEX] = 0;
278bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
279bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
280bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return result;
281bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
282bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
283bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updateDisplay(boolean announce) {
284bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mDayOfWeekView != null) {
285bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
286bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                    Locale.getDefault()));
287bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
288bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
289bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Compute indices of Month, Day and Year views
2907119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final String bestDateTimePattern =
2917119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette                DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
2927119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
293bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
2947119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position the Year and MonthAndDay views within the header.
2957119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthDayYearLayout.removeAllViews();
296bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[YEAR_INDEX] == 0) {
2977119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
2987119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
299518ff0de95e64116ecb07706fc564d4c19197ca7Alan Viverette        } else {
3007119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mMonthAndDayLayout);
3017119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette            mMonthDayYearLayout.addView(mHeaderYearTextView);
302bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
303bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
3047119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        // Position Day and Month views within the MonthAndDay view.
3057119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette        mMonthAndDayLayout.removeAllViews();
306bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
30760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
30860727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
309bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else {
31060727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderMonthTextView);
31160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
312bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
313bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
31460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
315bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                Locale.getDefault()).toUpperCase(Locale.getDefault()));
31660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
31760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
318bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
319bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // Accessibility.
320bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        long millis = mCurrentDate.getTimeInMillis();
321bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setDateMillis(millis);
322bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
323bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
324bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setContentDescription(monthAndDayText);
325bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
326bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (announce) {
327bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
328bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
329bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mAnimator.announceForAccessibility(fullDateText);
330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
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:
339e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette                mDayPickerView.setDay(getSelectedDay());
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        mDateChangedListener = callBack;
372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, monthOfYear);
374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void updateDate(int year, int month, int dayOfMonth) {
380bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
381bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.MONTH, month);
382bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
3839468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        if (mDateChangedListener != null) {
3849468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette            mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
3859468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette        }
386bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
387bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
390bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getYear() {
391bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.YEAR);
392bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
393bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
394bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
395bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getMonth() {
396bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.MONTH);
397bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
398bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
399bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
400bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getDayOfMonth() {
401bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
402bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
403bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
404bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
405bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMinDate(long minDate) {
406bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(minDate);
407bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
408bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
409bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
410bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
411bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.before(mTempDate)) {
412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(minDate);
413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
414bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(minDate);
41750eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
41850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMinDate() {
423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMinDate;
424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setMaxDate(long maxDate) {
428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mTempDate.setTimeInMillis(maxDate);
429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return;
432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
433bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentDate.after(mTempDate)) {
434bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.setTimeInMillis(maxDate);
435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updatePickers();
436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            updateDisplay(false);
437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(maxDate);
43950eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mDayPickerView.setRange(mMinDate, mMaxDate);
44050eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette        mYearPickerView.setRange(mMinDate, mMaxDate);
441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
442bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
443bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getMaxDate() {
445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mMaxDate;
446bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
448bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
4490a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
4500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        mFirstDayOfWeek = firstDayOfWeek;
451e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
452e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
4530a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    }
4540a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette
4550a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette    @Override
456bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public int getFirstDayOfWeek() {
4570a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        if (mFirstDayOfWeek != USE_LOCALE) {
4580a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette            return mFirstDayOfWeek;
4590a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette        }
460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate.getFirstDayOfWeek();
461bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
464bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setEnabled(boolean enabled) {
465bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMonthAndDayLayout.setEnabled(enabled);
46660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        mHeaderYearTextView.setEnabled(enabled);
467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mAnimator.setEnabled(enabled);
468bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mIsEnabled = enabled;
469bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean isEnabled() {
473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mIsEnabled;
474bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
475bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
476bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
477bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public CalendarView getCalendarView() {
478bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        throw new UnsupportedOperationException(
479bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                "CalendarView does not exists for the new DatePicker");
480bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
482bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
483bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setCalendarViewShown(boolean shown) {
484bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
485bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getCalendarViewShown() {
489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
490bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
491bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
492bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
493bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void setSpinnersShown(boolean shown) {
494bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // No-op for compatibility with the old DatePicker.
495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean getSpinnersShown() {
499bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return false;
500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onConfigurationChanged(Configuration newConfig) {
504bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Parcelable onSaveInstanceState(Parcelable superState) {
510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int year = mCurrentDate.get(Calendar.YEAR);
511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int month = mCurrentDate.get(Calendar.MONTH);
512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPosition = -1;
515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int listPositionOffset = -1;
516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (mCurrentView == MONTH_AND_DAY_VIEW) {
518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mDayPickerView.getMostVisiblePosition();
519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (mCurrentView == YEAR_VIEW) {
520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPosition = mYearPickerView.getFirstVisiblePosition();
521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            listPositionOffset = mYearPickerView.getFirstPositionOffset();
522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(),
525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset);
526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
529bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onRestoreInstanceState(Parcelable state) {
530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        SavedState ss = (SavedState) state;
531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
532a67d9095b7731df3a6ae3f45738a2980151fd1afCraig Mautner        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentView = ss.getCurrentView();
534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMinDate.setTimeInMillis(ss.getMinDate());
535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mMaxDate.setTimeInMillis(ss.getMaxDate());
536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(false);
538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(mCurrentView);
539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        final int listPosition = ss.getListPosition();
541bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (listPosition != -1) {
542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            if (mCurrentView == MONTH_AND_DAY_VIEW) {
543bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mDayPickerView.postSetSelection(listPosition);
544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            } else if (mCurrentView == YEAR_VIEW) {
545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        onPopulateAccessibilityEvent(event);
553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return true;
554bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
555bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
556bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
557bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
558bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.getText().add(mCurrentDate.getTime().toString());
559bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
560bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
561bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
562bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
563bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        event.setClassName(DatePicker.class.getName());
564bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
565bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
566bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
567bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
568bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        info.setClassName(DatePicker.class.getName());
569bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
570bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
571bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
572bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onYearSelected(int year) {
573bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
574bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mCurrentDate.set(Calendar.YEAR, year);
575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updatePickers();
576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        setCurrentView(MONTH_AND_DAY_VIEW);
577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        updateDisplay(true);
578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // If the newly selected month / year does not contain the currently selected day number,
581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    // change the selected day number to the last day of the selected month or year.
582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void adjustDayInMonthIfNeeded(int month, int year) {
585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        int daysInMonth = getDaysInMonth(month, year);
587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (day > daysInMonth) {
588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
590bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
591bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public static int getDaysInMonth(int month, int year) {
593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        switch (month) {
594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JANUARY:
595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MARCH:
596bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.MAY:
597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JULY:
598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.AUGUST:
599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.OCTOBER:
600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.DECEMBER:
601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 31;
602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.APRIL:
603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.JUNE:
604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.SEPTEMBER:
605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.NOVEMBER:
606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return 30;
607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            case Calendar.FEBRUARY:
608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return (year % 4 == 0) ? 29 : 28;
609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            default:
610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                throw new IllegalArgumentException("Invalid Month");
611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private void updatePickers() {
61560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette        for (OnDateChangedListener listener : mListeners) {
61660727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette            listener.onDateChanged();
617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
618e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
619e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        mDayPickerView.setDay(getSelectedDay());
620bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
621bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
622bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
623bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void registerOnDateChangedListener(OnDateChangedListener listener) {
624bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mListeners.add(listener);
625bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
626bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
627bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
628bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public Calendar getSelectedDay() {
629bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        return mCurrentDate;
630bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
631bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
632bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
633bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void tryVibrate() {
634bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
635bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
636bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
637bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    @Override
638bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    public void onClick(View v) {
639bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        tryVibrate();
640bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        if (v.getId() == R.id.date_picker_year) {
641bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(YEAR_VIEW);
642bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
643bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            setCurrentView(MONTH_AND_DAY_VIEW);
644bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
645bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
646bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
647bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    /**
648e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     * Listener called when the user selects a day in the day picker view.
649e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette     */
650e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    private final DayPickerView.OnDaySelectedListener
651e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mOnDaySelectedListener = new DayPickerView.OnDaySelectedListener() {
652e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        @Override
653e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        public void onDaySelected(DayPickerView view, Calendar day) {
654e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
655e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
656e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            updatePickers();
657e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            updateDisplay(true);
658e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
659e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette            tryVibrate();
660e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette        }
661e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    };
662e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette
663e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette    /**
664bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     * Class for managing state storing/restoring.
665bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio     */
666bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    private static class SavedState extends View.BaseSavedState {
667bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
668bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedYear;
669bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedMonth;
670bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mSelectedDay;
671bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMinDate;
672bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final long mMaxDate;
673bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mCurrentView;
674bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPosition;
675bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private final int mListPositionOffset;
676bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
677bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
678bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link DatePicker#onSaveInstanceState()}
679bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
680bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcelable superState, int year, int month, int day,
681bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                long minDate, long maxDate, int currentView, int listPosition,
682bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                int listPositionOffset) {
683bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(superState);
684bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = year;
685bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = month;
686bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = day;
687bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = minDate;
688bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = maxDate;
689bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = currentView;
690bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = listPosition;
691bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = listPositionOffset;
692bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
693bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
694bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        /**
695bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         * Constructor called from {@link #CREATOR}
696bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio         */
697bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        private SavedState(Parcel in) {
698bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super(in);
699bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedYear = in.readInt();
700bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedMonth = in.readInt();
701bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mSelectedDay = in.readInt();
702bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMinDate = in.readLong();
703bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mMaxDate = in.readLong();
704bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mCurrentView = in.readInt();
705bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPosition = in.readInt();
706bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            mListPositionOffset = in.readInt();
707bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
708bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
709bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @Override
710bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public void writeToParcel(Parcel dest, int flags) {
711bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            super.writeToParcel(dest, flags);
712bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedYear);
713bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedMonth);
714bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mSelectedDay);
715bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMinDate);
716bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeLong(mMaxDate);
717bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mCurrentView);
718bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPosition);
719bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            dest.writeInt(mListPositionOffset);
720bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
721bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
722bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedDay() {
723bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedDay;
724bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
725bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
726bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedMonth() {
727bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedMonth;
728bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
729bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
730bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getSelectedYear() {
731bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mSelectedYear;
732bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
733bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
734bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMinDate() {
735bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMinDate;
736bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
737bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
738bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public long getMaxDate() {
739bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mMaxDate;
740bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
741bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
742bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getCurrentView() {
743bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mCurrentView;
744bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
745bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
746bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPosition() {
747bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPosition;
748bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
749bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
750bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public int getListPositionOffset() {
751bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            return mListPositionOffset;
752bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        }
753bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
754bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        @SuppressWarnings("all")
755bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        // suppress unused and hiding
756bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
757bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
758bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState createFromParcel(Parcel in) {
759bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState(in);
760bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
761bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio
762bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            public SavedState[] newArray(int size) {
763bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio                return new SavedState[size];
764bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio            }
765bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio        };
766bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio    }
767bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio}
768