DatePickerCalendarDelegate.java revision 68640b68099765461d5427fddbb925beaa9d2a6a
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 196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport com.android.internal.R; 206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette 210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.annotation.Nullable; 22bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.Context; 23bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.ColorStateList; 24bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Configuration; 25bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.Resources; 26bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.content.res.TypedArray; 27c3e5a82691ac9094189a000430eab939e9020b2bAlan Viveretteimport android.icu.text.DisplayContext; 28c3e5a82691ac9094189a000430eab939e9020b2bAlan Viveretteimport android.icu.text.SimpleDateFormat; 2968763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar; 30bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.os.Parcelable; 31bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateFormat; 32bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.text.format.DateUtils; 33bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.util.AttributeSet; 340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.util.StateSet; 35bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.HapticFeedbackConstants; 36bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.LayoutInflater; 37bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.View; 380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.View.OnClickListener; 390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.ViewGroup; 40bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport android.view.accessibility.AccessibilityEvent; 410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.DayPickerView.OnDaySelectedListener; 420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.YearPickerView.OnYearSelectedListener; 43bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 44bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglioimport java.util.Locale; 45bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 46bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio/** 47bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio * A delegate for picking up a date (day / month / year). 48bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio */ 490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteclass DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate { 500a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette private static final int USE_LOCALE = 0; 51bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 52bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private static final int UNINITIALIZED = -1; 530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private static final int VIEW_MONTH_DAY = 0; 540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private static final int VIEW_YEAR = 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 6160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private static final int[] ATTRS_TEXT_COLOR = new int[] { 6260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette com.android.internal.R.attr.textColor}; 6360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private static final int[] ATTRS_DISABLED_ALPHA = new int[] { 640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette com.android.internal.R.attr.disabledAlpha}; 65bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private SimpleDateFormat mYearFormat; 670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private SimpleDateFormat mMonthDayFormat; 687119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette 690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Top-level container. 700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ViewGroup mContainer; 717119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette 720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Header views. 730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private TextView mHeaderYear; 740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private TextView mHeaderMonthDay; 757119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette 760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Picker views. 770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ViewAnimator mAnimator; 78bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private DayPickerView mDayPickerView; 79bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private YearPickerView mYearPickerView; 80bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 81bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio // Accessibility strings. 82bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private String mSelectDay; 83bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private String mSelectYear; 84bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 85bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private int mCurrentView = UNINITIALIZED; 86bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 87452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette private final Calendar mCurrentDate; 88452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette private final Calendar mTempDate; 89452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette private final Calendar mMinDate; 90452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette private final Calendar mMaxDate; 91bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 920a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette private int mFirstDayOfWeek = USE_LOCALE; 930a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette 943053b2fdcf7486f2e2f572f9b05ce65dacdd2b4cChet Haase public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs, 95bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio int defStyleAttr, int defStyleRes) { 96bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio super(delegator, context); 97bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final Locale locale = mCurrentLocale; 99452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette mCurrentDate = Calendar.getInstance(locale); 100452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette mTempDate = Calendar.getInstance(locale); 101452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette mMinDate = Calendar.getInstance(locale); 102452fe349841476e4c7d17ab0652bdd4d45ce4595Alan Viverette mMaxDate = Calendar.getInstance(locale); 103bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 10449e6c4adbfad8cac28a0c7c68918b443a64a07d8You Kim mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); 10549e6c4adbfad8cac28a0c7c68918b443a64a07d8You Kim mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); 106bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 10760727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette final Resources res = mDelegator.getResources(); 108bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final TypedArray a = mContext.obtainStyledAttributes(attrs, 109bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio R.styleable.DatePicker, defStyleAttr, defStyleRes); 110bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 111bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio Context.LAYOUT_INFLATER_SERVICE); 112bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final int layoutResourceId = a.getResourceId( 1130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette R.styleable.DatePicker_internalLayout, R.layout.date_picker_material); 1140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up and attach container. 116f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mContainer = (ViewGroup) inflater.inflate(layoutResourceId, mDelegator, false); 117f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mDelegator.addView(mContainer); 118bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 1190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up header views. 1200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header); 1210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year); 1220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear.setOnClickListener(mOnHeaderClickListener); 1230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date); 1240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener); 125ba9bf41a77261471a4dc9d7964aec41726b4e4e6Alan Viverette 1260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // For the sake of backwards compatibility, attempt to extract the text 1270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // color from the header month text appearance. If it's set, we'll let 1280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // that override the "real" header text color. 1290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette ColorStateList headerTextColor = null; 130bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 1310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @SuppressWarnings("deprecation") 1320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int monthHeaderTextAppearance = a.getResourceId( 1334e5168fae43e783a35c5bc731e500196005268fbAlan Viverette R.styleable.DatePicker_headerMonthTextAppearance, 0); 1340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (monthHeaderTextAppearance != 0) { 1350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final TypedArray textAppearance = mContext.obtainStyledAttributes(null, 1360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette ATTRS_TEXT_COLOR, 0, monthHeaderTextAppearance); 1370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final ColorStateList legacyHeaderTextColor = textAppearance.getColorStateList(0); 1380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette headerTextColor = applyLegacyColorFixes(legacyHeaderTextColor); 1390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette textAppearance.recycle(); 140bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 14160727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette 1420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (headerTextColor == null) { 1430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette headerTextColor = a.getColorStateList(R.styleable.DatePicker_headerTextColor); 14460727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette } 14560727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette 1460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (headerTextColor != null) { 1470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear.setTextColor(headerTextColor); 1480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay.setTextColor(headerTextColor); 14960727e07c6ef72e2f494266939c02494a3df28f8Alan Viverette } 150bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 1510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up header background, if available. 1520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (a.hasValueOrEmpty(R.styleable.DatePicker_headerBackground)) { 1530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette header.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground)); 1540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 15660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette a.recycle(); 15760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 1580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up picker container. 1590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator); 1600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up day picker view. 1620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker); 163e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek); 1644612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mDayPickerView.setMinDate(mMinDate.getTimeInMillis()); 1654612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis()); 1664612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mDayPickerView.setDate(mCurrentDate.getTimeInMillis()); 167e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener); 16850eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette 1690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up year picker view. 1700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker); 1712a90fa6d94b7d31e997493d2d0601e5129ec7c3eAlan Viverette mYearPickerView.setRange(mMinDate, mMaxDate); 172e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount mYearPickerView.setYear(mCurrentDate.get(Calendar.YEAR)); 1730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener); 1744e5168fae43e783a35c5bc731e500196005268fbAlan Viverette 1750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set up content descriptions. 176bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mSelectDay = res.getString(R.string.select_day); 177bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mSelectYear = res.getString(R.string.select_year); 178bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 1790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Initialize for current locale. This also initializes the date, so no 1800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // need to call onDateChanged. 1810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette onLocaleChanged(mCurrentLocale); 1820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setCurrentView(VIEW_MONTH_DAY); 1840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 1870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * The legacy text color might have been poorly defined. Ensures that it 1880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * has an appropriate activated state, using the selected state if one 1890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * exists or modifying the default text color otherwise. 1900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 1910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param color a legacy text color, or {@code null} 1920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @return a color state list with an appropriate activated state, or 1930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * {@code null} if a valid activated state could not be generated 1940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 1950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Nullable 1960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ColorStateList applyLegacyColorFixes(@Nullable ColorStateList color) { 1970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (color == null || color.hasState(R.attr.state_activated)) { 1980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return color; 1990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int activatedColor; 2020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int defaultColor; 2030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (color.hasState(R.attr.state_selected)) { 2040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette activatedColor = color.getColorForState(StateSet.get( 2050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_SELECTED), 0); 2060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette defaultColor = color.getColorForState(StateSet.get( 2070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette StateSet.VIEW_STATE_ENABLED), 0); 2080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } else { 2090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette activatedColor = color.getDefaultColor(); 2100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Generate a non-activated color using the disabled alpha. 2120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final TypedArray ta = mContext.obtainStyledAttributes(ATTRS_DISABLED_ALPHA); 2130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final float disabledAlpha = ta.getFloat(0, 0.30f); 2140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette defaultColor = multiplyAlphaComponent(activatedColor, disabledAlpha); 2150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2167119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette 2170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (activatedColor == 0 || defaultColor == 0) { 2180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // We somehow failed to obtain the colors. 2190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return null; 2200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2217119d0d66bd8649508c5bbb973a34b3b858bf8cfAlan Viverette 2220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int[][] stateSet = new int[][] {{ R.attr.state_activated }, {}}; 2230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int[] colors = new int[] { activatedColor, defaultColor }; 2240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return new ColorStateList(stateSet, colors); 2250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 226bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 2270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int multiplyAlphaComponent(int color, float alphaMod) { 2280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int srcRgb = color & 0xFFFFFF; 2290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int srcAlpha = (color >> 24) & 0xFF; 2300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int dstAlpha = (int) (srcAlpha * alphaMod + 0.5f); 2310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return srcRgb | (dstAlpha << 24); 232bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 233bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 234bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio /** 2350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Listener called when the user selects a day in the day picker view. 2360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 2370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final OnDaySelectedListener mOnDaySelectedListener = new OnDaySelectedListener() { 2380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void onDaySelected(DayPickerView view, Calendar day) { 2400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mCurrentDate.setTimeInMillis(day.getTimeInMillis()); 2410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette onDateChanged(true, true); 2420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette }; 2440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 2460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Listener called when the user selects a year in the year picker view. 2470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 2480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final OnYearSelectedListener mOnYearSelectedListener = new OnYearSelectedListener() { 2490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void onYearChanged(YearPickerView view, int year) { 2510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // If the newly selected month / year does not contain the 2520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // currently selected day number, change the selected day number 2530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // to the last day of the selected month or year. 2540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30 2550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013 2560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH); 2570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int month = mCurrentDate.get(Calendar.MONTH); 2580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int daysInMonth = getDaysInMonth(month, year); 2590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (day > daysInMonth) { 2600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth); 2610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mCurrentDate.set(Calendar.YEAR, year); 2640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette onDateChanged(true, true); 2650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Automatically switch to day picker. 2670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setCurrentView(VIEW_MONTH_DAY); 268e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount 269e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount // Switch focus back to the year text. 270e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount mHeaderYear.requestFocus(); 2710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette }; 2730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 2750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Listener called when the user clicks on a header item. 2760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 2770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final OnClickListener mOnHeaderClickListener = new OnClickListener() { 2780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void onClick(View v) { 2800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette tryVibrate(); 2810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette switch (v.getId()) { 2830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette case R.id.date_picker_header_year: 2840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setCurrentView(VIEW_YEAR); 2850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette break; 2860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette case R.id.date_picker_header_date: 2870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setCurrentView(VIEW_MONTH_DAY); 2880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette break; 2890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette }; 2920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette protected void onLocaleChanged(Locale locale) { 2950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final TextView headerYear = mHeaderYear; 2960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (headerYear == null) { 2970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Abort, we haven't initialized yet. This method will get called 2980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // again later after everything has been set up. 2990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return; 300bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 301bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Update the date formatter. 3030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String datePattern = DateFormat.getBestDateTimePattern(locale, "EMMMd"); 3040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mMonthDayFormat = new SimpleDateFormat(datePattern, locale); 305c3e5a82691ac9094189a000430eab939e9020b2bAlan Viverette mMonthDayFormat.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE); 3060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mYearFormat = new SimpleDateFormat("y", locale); 307bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Update the header text. 3090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette onCurrentDateChanged(false); 3100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 311bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private void onCurrentDateChanged(boolean announce) { 3130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mHeaderYear == null) { 3140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Abort, we haven't initialized yet. This method will get called 3150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // again later after everything has been set up. 3160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return; 317bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 318bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String year = mYearFormat.format(mCurrentDate.getTime()); 3200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear.setText(year); 321bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String monthDay = mMonthDayFormat.format(mCurrentDate.getTime()); 3230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay.setText(monthDay); 324bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 3250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // TODO: This should use live regions. 326bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (announce) { 3270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final long millis = mCurrentDate.getTimeInMillis(); 3280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; 3290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final String fullDateText = DateUtils.formatDateTime(mContext, millis, flags); 330bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mAnimator.announceForAccessibility(fullDateText); 331bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 332bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 333bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 334bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio private void setCurrentView(final int viewIndex) { 335bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio switch (viewIndex) { 3360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette case VIEW_MONTH_DAY: 3370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayPickerView.setDate(mCurrentDate.getTimeInMillis()); 3380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 339bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mCurrentView != viewIndex) { 3400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay.setActivated(true); 3410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear.setActivated(false); 3420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAnimator.setDisplayedChild(VIEW_MONTH_DAY); 343bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentView = viewIndex; 344bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 345bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 346bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mAnimator.announceForAccessibility(mSelectDay); 347bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio break; 3480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette case VIEW_YEAR: 349e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount final int year = mCurrentDate.get(Calendar.YEAR); 350e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount mYearPickerView.setYear(year); 351e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount mYearPickerView.post(new Runnable() { 352e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount @Override 353e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount public void run() { 354e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount mYearPickerView.requestFocus(); 355e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount final View selected = mYearPickerView.getSelectedView(); 356e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount if (selected != null) { 357e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount selected.requestFocus(); 358e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount } 359e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount } 360e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount }); 3610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 362bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mCurrentView != viewIndex) { 3630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderMonthDay.setActivated(false); 3640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mHeaderYear.setActivated(true); 3650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mAnimator.setDisplayedChild(VIEW_YEAR); 366bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentView = viewIndex; 367bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 368bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 369bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mAnimator.announceForAccessibility(mSelectYear); 370bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio break; 371bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 372bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 373bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 374bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 375bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void init(int year, int monthOfYear, int dayOfMonth, 376bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio DatePicker.OnDateChangedListener callBack) { 377bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.YEAR, year); 378bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.MONTH, monthOfYear); 379bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); 380e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 3810cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette onDateChanged(false, false); 382a9a75f506efe7e63078bed661f49992e501846f0Alan Viverette 38368640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri mOnDateChangedListener = callBack; 384bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 385bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 386bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 387bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void updateDate(int year, int month, int dayOfMonth) { 388bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.YEAR, year); 389bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.MONTH, month); 390bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); 391e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 3920cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette onDateChanged(false, true); 393e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette } 394e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 3950cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette private void onDateChanged(boolean fromUser, boolean callbackToClient) { 3960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int year = mCurrentDate.get(Calendar.YEAR); 3970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 39868640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri if (callbackToClient && mOnDateChangedListener != null) { 399e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette final int monthOfYear = mCurrentDate.get(Calendar.MONTH); 400e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH); 40168640b68099765461d5427fddbb925beaa9d2a6aClara Bayarri mOnDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth); 402e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette } 403e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 4040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayPickerView.setDate(mCurrentDate.getTimeInMillis()); 4050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mYearPickerView.setYear(year); 406e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 4070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette onCurrentDateChanged(fromUser); 408e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette 409e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette if (fromUser) { 410e6ec07fc5d7ce7732f63b6da73d3cc9e207df69fAlan Viverette tryVibrate(); 4119468c6a28e696f4ddca2c5b9ba312ffb590c3161Alan Viverette } 412bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 413bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 414bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 415bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public int getYear() { 416bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mCurrentDate.get(Calendar.YEAR); 417bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 418bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 419bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 420bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public int getMonth() { 421bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mCurrentDate.get(Calendar.MONTH); 422bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 423bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 424bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 425bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public int getDayOfMonth() { 426bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mCurrentDate.get(Calendar.DAY_OF_MONTH); 427bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 428bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 429bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 430bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void setMinDate(long minDate) { 431bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mTempDate.setTimeInMillis(minDate); 432bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR) 4333fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) { 4343fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette // Same day, no-op. 435bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return; 436bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 437bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mCurrentDate.before(mTempDate)) { 438bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.setTimeInMillis(minDate); 4390cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette onDateChanged(false, true); 440bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 441bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mMinDate.setTimeInMillis(minDate); 4424612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mDayPickerView.setMinDate(minDate); 44350eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette mYearPickerView.setRange(mMinDate, mMaxDate); 444bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 445bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 446bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 447bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public Calendar getMinDate() { 448bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mMinDate; 449bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 450bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 451bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 452bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void setMaxDate(long maxDate) { 453bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mTempDate.setTimeInMillis(maxDate); 454bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR) 4553fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) { 4563fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette // Same day, no-op. 457bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return; 458bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 459bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio if (mCurrentDate.after(mTempDate)) { 460bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mCurrentDate.setTimeInMillis(maxDate); 4610cecbc9c7208f918ddf9d117057649f6e132069fAlan Viverette onDateChanged(false, true); 462bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 463bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mMaxDate.setTimeInMillis(maxDate); 4644612740ddc76b3518dc6d189d5f8b5b7f60e9d64Alan Viverette mDayPickerView.setMaxDate(maxDate); 46550eb025c2fea7e364e0be951ce8ba6ca605f901aAlan Viverette mYearPickerView.setRange(mMinDate, mMaxDate); 466bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 467bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 468bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 469bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public Calendar getMaxDate() { 470bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mMaxDate; 471bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 472bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 473bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 4740a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette public void setFirstDayOfWeek(int firstDayOfWeek) { 4750a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette mFirstDayOfWeek = firstDayOfWeek; 476e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette 477e763c9bd6ed0ca46daafc21fc4313ebcad4bcafaAlan Viverette mDayPickerView.setFirstDayOfWeek(firstDayOfWeek); 4780a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette } 4790a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette 4800a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette @Override 481bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public int getFirstDayOfWeek() { 4820a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette if (mFirstDayOfWeek != USE_LOCALE) { 4830a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette return mFirstDayOfWeek; 4840a04bb0d4bf18318fe5473bf5615c2016bc26373Alan Viverette } 485bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return mCurrentDate.getFirstDayOfWeek(); 486bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 487bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 488bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 489bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void setEnabled(boolean enabled) { 490f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mContainer.setEnabled(enabled); 491f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mDayPickerView.setEnabled(enabled); 492f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mYearPickerView.setEnabled(enabled); 493f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mHeaderYear.setEnabled(enabled); 494f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette mHeaderMonthDay.setEnabled(enabled); 495bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 496bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 497bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 498bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public boolean isEnabled() { 4990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mContainer.isEnabled(); 500bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 501bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 502bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 503bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public CalendarView getCalendarView() { 504f7aa9251d091d0e52e879a8a92bd38228e58efd9Alan Viverette throw new UnsupportedOperationException("Not supported by calendar-mode DatePicker"); 505bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 506bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 507bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 508bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void setCalendarViewShown(boolean shown) { 509bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio // No-op for compatibility with the old DatePicker. 510bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 511bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 512bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 513bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public boolean getCalendarViewShown() { 514bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return false; 515bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 516bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 517bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 518bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void setSpinnersShown(boolean shown) { 519bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio // No-op for compatibility with the old DatePicker. 520bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 521bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 522bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 523bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public boolean getSpinnersShown() { 524bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return false; 525bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 526bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 527bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 528bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void onConfigurationChanged(Configuration newConfig) { 5290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setCurrentLocale(newConfig.locale); 530bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 531bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 532bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 533bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public Parcelable onSaveInstanceState(Parcelable superState) { 534bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final int year = mCurrentDate.get(Calendar.YEAR); 535bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final int month = mCurrentDate.get(Calendar.MONTH); 536bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH); 537bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 538bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio int listPosition = -1; 539bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio int listPositionOffset = -1; 540bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 5410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mCurrentView == VIEW_MONTH_DAY) { 542bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio listPosition = mDayPickerView.getMostVisiblePosition(); 5430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } else if (mCurrentView == VIEW_YEAR) { 544bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio listPosition = mYearPickerView.getFirstVisiblePosition(); 545bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio listPositionOffset = mYearPickerView.getFirstPositionOffset(); 546bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 547bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 548bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return new SavedState(superState, year, month, day, mMinDate.getTimeInMillis(), 549bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mMaxDate.getTimeInMillis(), mCurrentView, listPosition, listPositionOffset); 550bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 551bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 552bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 553bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void onRestoreInstanceState(Parcelable state) { 5546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette if (state instanceof SavedState) { 5556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette final SavedState ss = (SavedState) state; 5566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette 5576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette // TODO: Move instance state into DayPickerView, YearPickerView. 5586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay()); 5596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette mMinDate.setTimeInMillis(ss.getMinDate()); 5606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette mMaxDate.setTimeInMillis(ss.getMaxDate()); 5616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette 5626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette onCurrentDateChanged(false); 5636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette 5646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette final int currentView = ss.getCurrentView(); 5656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette setCurrentView(currentView); 5666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette 5676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette final int listPosition = ss.getListPosition(); 5686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette if (listPosition != -1) { 5696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette if (currentView == VIEW_MONTH_DAY) { 5706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette mDayPickerView.setPosition(listPosition); 5716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette } else if (currentView == VIEW_YEAR) { 5726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette final int listPositionOffset = ss.getListPositionOffset(); 5736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset); 5746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette } 575bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 576bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 577bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 578bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 579bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 580bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 581bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio onPopulateAccessibilityEvent(event); 582bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return true; 583bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 584bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 585bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio @Override 586bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 587bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio event.getText().add(mCurrentDate.getTime().toString()); 588bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 589bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 590a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn public CharSequence getAccessibilityClassName() { 591a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn return DatePicker.class.getName(); 592bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 593bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 594bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio public static int getDaysInMonth(int month, int year) { 595bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio switch (month) { 596bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.JANUARY: 597bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.MARCH: 598bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.MAY: 599bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.JULY: 600bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.AUGUST: 601bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.OCTOBER: 602bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.DECEMBER: 603bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return 31; 604bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.APRIL: 605bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.JUNE: 606bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.SEPTEMBER: 607bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.NOVEMBER: 608bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return 30; 609bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio case Calendar.FEBRUARY: 610bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio return (year % 4 == 0) ? 29 : 28; 611bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio default: 612bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio throw new IllegalArgumentException("Invalid Month"); 613bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 614bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 615bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio 6160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private void tryVibrate() { 617bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE); 618bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio } 619bd9152f6ee156ee473f05f6f05f238605996fca4Fabrice Di Meglio} 620