DatePicker.java revision 3fec3fe0e3a83c5e0d1264f34bcc55b158537bc6
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 21f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport android.content.res.Configuration; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 25e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.text.TextUtils; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.DateFormat; 27dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport android.text.format.DateUtils; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 29e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.util.Log; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 328a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 333fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganovimport android.view.accessibility.AccessibilityManager; 34cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganovimport android.widget.NumberPicker.OnValueChangeListener; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport com.android.internal.R; 37f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 38e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.text.ParseException; 3903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat; 40156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganovimport java.util.Arrays; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 42dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale; 43e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.util.TimeZone; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 46e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * This class is a widget for selecting a date. The date can be selected by a 47e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * year, month, and day spinners or a {@link CalendarView}. The set of spinners 48e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * and the calendar view are automatically synchronized. The client can 49e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * customize whether only the spinners, or only the calendar view, or both to be 50e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * displayed. Also the minimal and maximal date from which dates to be selected 51e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * can be customized. 5250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p> 539a143e6641fa4a5942e7341007d916601402e8dfDirk Dougherty * See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date 549a143e6641fa4a5942e7341007d916601402e8dfDirk Dougherty * Picker tutorial</a>. 5550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p> 56e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}. 58e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p> 59e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 60e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear 61e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear 62e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate 63e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate 64e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown 65e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String LOG_TAG = DatePicker.class.getSimpleName(); 71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 72e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String DATE_FORMAT = "MM/dd/yyyy"; 73e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DEFAULT_START_YEAR = 1900; 75dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 7650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static final int DEFAULT_END_YEAR = 2100; 77dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 78e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true; 79e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 80e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_SPINNERS_SHOWN = true; 8150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 8225f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private static final boolean DEFAULT_ENABLED_STATE = true; 8325f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov 84e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mDaySpinner; 8550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 86e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final LinearLayout mSpinners; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 88e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mMonthSpinner; 89e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 90e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mYearSpinner; 91e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 92e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final CalendarView mCalendarView; 9350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 94f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Locale mCurrentLocale; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private OnDateChangedListener mOnDateChangedListener; 9750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 98f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private String[] mShortMonths; 9950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 100f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT); 10150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 102f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private int mNumberOfMonths; 103dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 104f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mTempDate; 105e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 106f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mMinDate; 107e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 108f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mMaxDate; 109e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 110f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mCurrentDate; 111e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 11225f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private boolean mIsEnabled = DEFAULT_ENABLED_STATE; 11351c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 115e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * The callback used to indicate the user changes\d the date. 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDateChangedListener { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 120e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Called upon a date change. 121e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view associated with this listener. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The year that was set. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param monthOfYear The month that was set (0-11) for compatibility 12550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * with {@link java.util.Calendar}. 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The day of the month that was set. 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs) { 1364243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov this(context, attrs, R.attr.datePickerStyle); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs, int defStyle) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 142f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov // initialization based on locale 143f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov setCurrentLocale(Locale.getDefault()); 144f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 1454243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker, 1464243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov defStyle, 0); 147e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown, 148e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov DEFAULT_SPINNERS_SHOWN); 149e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean calendarViewShown = attributesArray.getBoolean( 150e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN); 1514243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear, 1524243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov DEFAULT_START_YEAR); 153e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); 154e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String minDate = attributesArray.getString(R.styleable.DatePicker_minDate); 155e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate); 1564243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_layout, 1574243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov R.layout.date_picker); 158e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov attributesArray.recycle(); 159e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 16050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov LayoutInflater inflater = (LayoutInflater) context 16150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 1624243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov inflater.inflate(layoutResourceId, this, true); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 164cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganov OnValueChangeListener onChangeListener = new OnValueChangeListener() { 165e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 166156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); 167156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // take care of wrapping of days and months to update greater fields 168156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (picker == mDaySpinner) { 169156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH); 170156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == maxDayOfMonth && newVal == 1) { 171156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, 1); 172156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 1 && newVal == maxDayOfMonth) { 173156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, -1); 174156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 175156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal); 176156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 177156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mMonthSpinner) { 178156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == 11 && newVal == 0) { 179156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, 1); 180156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 0 && newVal == 11) { 181156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, -1); 182156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 183156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, newVal - oldVal); 184156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 185156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mYearSpinner) { 186156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.set(Calendar.YEAR, newVal); 187156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 188156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov throw new IllegalArgumentException(); 189156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 190156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // now set the date to the adjusted one 191156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH), 192156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.get(Calendar.DAY_OF_MONTH)); 19358f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 19458f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 195156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 1985fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 199e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners = (LinearLayout) findViewById(R.id.pickers); 200e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 201e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // calendar view day-picker 202e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView = (CalendarView) findViewById(R.id.calendar_view); 203e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { 204e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) { 205156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, monthDay); 20658f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 207156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 20828104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 20928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov }); 21028104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 21150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // day 212e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner = (NumberPicker) findViewById(R.id.day); 213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); 214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnLongPressUpdateInterval(100); 215e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnValueChangedListener(onChangeListener); 2165fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 21750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // month 218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner = (NumberPicker) findViewById(R.id.month); 219e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMinValue(0); 220e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMaxValue(mNumberOfMonths - 1); 221f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMonthSpinner.setDisplayedValues(mShortMonths); 222e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnLongPressUpdateInterval(200); 223e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnValueChangedListener(onChangeListener); 22450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 22550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // year 226e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner = (NumberPicker) findViewById(R.id.year); 227e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnLongPressUpdateInterval(100); 228e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnValueChangedListener(onChangeListener); 229e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 230e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show only what the user required but make sure we 231e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show something and the spinners have higher priority 232e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!spinnersShown && !calendarViewShown) { 233e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(true); 234e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else { 235e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(spinnersShown); 236e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setCalendarViewShown(calendarViewShown); 23713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } 238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 23913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // set the min date giving priority of the minDate over startYear 24013427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.clear(); 24113427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!TextUtils.isEmpty(minDate)) { 24213427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!parseDate(minDate, mTempDate)) { 243e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(startYear, 0, 1); 244e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 24513427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } else { 24613427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.set(startYear, 0, 1); 24713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } 24813427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov setMinDate(mTempDate.getTimeInMillis()); 24913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov 25013427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // set the max date giving priority of the maxDate over endYear 25113427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.clear(); 25213427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!TextUtils.isEmpty(maxDate)) { 25313427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!parseDate(maxDate, mTempDate)) { 254e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(endYear, 11, 31); 255e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 25613427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } else { 25713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.set(endYear, 11, 31); 258e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 25913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov setMaxDate(mTempDate.getTimeInMillis()); 26013427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov 26113427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // initialize to current date 26213427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mCurrentDate.setTimeInMillis(System.currentTimeMillis()); 26313427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate 26413427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov .get(Calendar.DAY_OF_MONTH), null); 265e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 266e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // re-order the number spinners to match the current date format 267e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov reorderSpinners(); 2683fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov 2693fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov // set content descriptions 2703fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov if (AccessibilityManager.getInstance(mContext).isEnabled()) { 2713fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov setContentDescriptions(); 2723fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov } 273e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 274e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 275e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 276e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the minimal date supported by this {@link DatePicker} in 277e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 278e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 279e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 280e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default minimal date is 01/01/1900. 281e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 282e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 283e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The minimal supported date. 284e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 285e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMinDate() { 286e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMinDate(); 287e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 288e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 289e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 290e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the minimal date supported by this {@link NumberPicker} in 291e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 292e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 293e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 294e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param minDate The minimal supported date. 295e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 296e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMinDate(long minDate) { 297e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(minDate); 298e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR) 299e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) { 300e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 301e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 302e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMinDate.setTimeInMillis(minDate); 303e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMinDate(minDate); 304156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 305156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 306156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 307156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 308156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 31128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov /** 312e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the maximal date supported by this {@link DatePicker} in 313e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 314e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 315e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 316e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default maximal date is 12/31/2100. 31728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * <p> 31828104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * 319e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The maximal supported date. 320e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 321e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMaxDate() { 322e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMaxDate(); 323e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 324e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 325e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 326e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the maximal date supported by this {@link DatePicker} in 327e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 328e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 329e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 330e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param maxDate The maximal supported date. 33128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov */ 332e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMaxDate(long maxDate) { 333e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(maxDate); 334e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR) 335e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) { 336e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 33728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 338e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMaxDate.setTimeInMillis(maxDate); 339e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMaxDate(maxDate); 340156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.after(mMaxDate)) { 341156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 342156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 343156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 344156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 34528104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 34628104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setEnabled(boolean enabled) { 34951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov if (mIsEnabled == enabled) { 35051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return; 35151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setEnabled(enabled); 353e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setEnabled(enabled); 354e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setEnabled(enabled); 355e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setEnabled(enabled); 356e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setEnabled(enabled); 35751c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov mIsEnabled = enabled; 35851c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 35951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 36051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov @Override 36151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov public boolean isEnabled() { 36251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return mIsEnabled; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3658a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov @Override 3663fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3673fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov onPopulateAccessibilityEvent(event); 3683fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov return true; 3693fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov } 3703fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov 3713fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov @Override 372736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 373736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov super.onPopulateAccessibilityEvent(event); 374736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 3753fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; 3768a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov String selectedDateUtterance = DateUtils.formatDateTime(mContext, 3778a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov mCurrentDate.getTimeInMillis(), flags); 3788a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov event.getText().add(selectedDateUtterance); 3798a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov } 3808a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov 381f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov @Override 382f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov protected void onConfigurationChanged(Configuration newConfig) { 383f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov super.onConfigurationChanged(newConfig); 384f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov setCurrentLocale(newConfig.locale); 385f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 386f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 38750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 388e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the {@link CalendarView} is shown. 389e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 390e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the calendar view is shown. 3915f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @see #getCalendarView() 392e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 393e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getCalendarViewShown() { 394e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.isShown(); 395e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 396e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 397e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 3985f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * Gets the {@link CalendarView}. 3995f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * 4005f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @return The calendar view. 4015f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @see #getCalendarViewShown() 4025f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov */ 4035f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov public CalendarView getCalendarView () { 4045f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov return mCalendarView; 4055f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov } 4065f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov 4075f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov /** 408e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the {@link CalendarView} is shown. 409e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 410e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the calendar view is to be shown. 411e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 412e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setCalendarViewShown(boolean shown) { 413e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setVisibility(shown ? VISIBLE : GONE); 414e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 415e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 416e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 417e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the spinners are shown. 418e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 419e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the spinners are shown. 42050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 421e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getSpinnersShown() { 422e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mSpinners.isShown(); 423e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 424e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 425e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 426e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the spinners are shown. 427e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 428e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the spinners are to be shown. 429e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 430e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setSpinnersShown(boolean shown) { 431e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners.setVisibility(shown ? VISIBLE : GONE); 432e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 433e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 434e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 435f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * Sets the current locale. 436f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * 437f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param locale The current locale. 438f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov */ 439f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private void setCurrentLocale(Locale locale) { 440f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov if (locale.equals(mCurrentLocale)) { 441f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return; 442f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 443f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 444f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mCurrentLocale = locale; 445f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 446f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mTempDate = getCalendarForLocale(mTempDate, locale); 447f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMinDate = getCalendarForLocale(mMinDate, locale); 448f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMaxDate = getCalendarForLocale(mMaxDate, locale); 449f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mCurrentDate = getCalendarForLocale(mCurrentDate, locale); 450f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 451f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1; 452f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mShortMonths = new String[mNumberOfMonths]; 453f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov for (int i = 0; i < mNumberOfMonths; i++) { 454f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i, 455f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov DateUtils.LENGTH_MEDIUM); 456f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 457f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 458f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 459f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov /** 460f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * Gets a calendar for locale bootstrapped with the value of a given calendar. 461f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * 462f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param oldCalendar The old calendar. 463f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param locale The locale. 464f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov */ 465f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) { 466f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov if (oldCalendar == null) { 467f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return Calendar.getInstance(locale); 468f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } else { 469f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov final long currentTimeMillis = oldCalendar.getTimeInMillis(); 470f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov Calendar newCalendar = Calendar.getInstance(locale); 471f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov newCalendar.setTimeInMillis(currentTimeMillis); 472f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return newCalendar; 473f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 474f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 475f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 476f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov /** 477f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * Reorders the spinners according to the date format that is 478f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * explicitly set by the user and if no such is set fall back 479f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * to the current locale's default format. 480e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 481e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void reorderSpinners() { 482f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.removeAllViews(); 483f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov char[] order = DateFormat.getDateFormatOrder(getContext()); 484f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov for (int i = 0; i < order.length; i++) { 485f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov switch (order[i]) { 486f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov case DateFormat.DATE: 487f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mDaySpinner); 488f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 489f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov case DateFormat.MONTH: 490f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mMonthSpinner); 491f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 492f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov case DateFormat.YEAR: 493f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mYearSpinner); 494f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 495f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov default: 496f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov throw new IllegalArgumentException(); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 50250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Updates the current date. 50350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 50450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param year The year. 50550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param month The month which is <strong>starting from zero</strong>. 50650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param dayOfMonth The day of the month. 50750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 50850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void updateDate(int year, int month, int dayOfMonth) { 509156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (!isNewDate(year, month, dayOfMonth)) { 510156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return; 511dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 512156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, dayOfMonth); 51358f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 51458f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 515156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 516dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 517dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 51850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // Override so we are in complete control of save / restore for this widget. 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchThawSelfOnly(container); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Parcelable onSaveInstanceState() { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcelable superState = super.onSaveInstanceState(); 527156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return new SavedState(superState, getYear(), getMonth(), getDayOfMonth()); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onRestoreInstanceState(Parcelable state) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState ss = (SavedState) state; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onRestoreInstanceState(ss.getSuperState()); 534156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(ss.mYear, ss.mMonth, ss.mDay); 53558f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 53658f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 54050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Initialize the state. If the provided values designate an inconsistent 541e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * date the values are normalized before updating the spinners. 54250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The initial year. 54450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param monthOfYear The initial month <strong>starting from zero</strong>. 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The initial day of the month. 54650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param onDateChangedListener How user is notified date is changed by 54750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * user, can be null. 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void init(int year, int monthOfYear, int dayOfMonth, 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnDateChangedListener onDateChangedListener) { 551156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, monthOfYear, dayOfMonth); 55258f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 55358f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 5542f136a874d240cc7e85e8de9c7644a7daa9532daSvetoslav Ganov mOnDateChangedListener = onDateChangedListener; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 558e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Parses the given <code>date</code> and in case of success sets the result 559e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * to the <code>outDate</code>. 560a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov * 561e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the date was parsed. 562a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov */ 563e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private boolean parseDate(String date, Calendar outDate) { 564e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov try { 565e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov outDate.setTime(mDateFormat.parse(date)); 566e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return true; 567e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } catch (ParseException e) { 568e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT); 569e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return false; 570e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 571a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 572a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov 573156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private boolean isNewDate(int year, int month, int dayOfMonth) { 574156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return (mCurrentDate.get(Calendar.YEAR) != year 575156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.MONTH) != dayOfMonth 576156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month); 577156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 578e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 579156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void setDate(int year, int month, int dayOfMonth) { 580156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.set(year, month, dayOfMonth); 581e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 582e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 583e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else if (mCurrentDate.after(mMaxDate)) { 584e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 585e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 586e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 587e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 588156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void updateSpinners() { 589156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner ranges respecting the min and max dates 590156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.equals(mMinDate)) { 591156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 592156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 593156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 594156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 595156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH)); 596156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH)); 597156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 598156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (mCurrentDate.equals(mMaxDate)) { 599156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH)); 600156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 601156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 602156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 603156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH)); 604156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH)); 605156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 606156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 607156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(1); 608156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 609156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(true); 610156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 611156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(0); 612156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(11); 613156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(true); 614e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 615e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 616156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // make sure the month names are a zero based array 617156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // with the months in the month spinner 618f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov String[] displayedValues = Arrays.copyOfRange(mShortMonths, 619156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1); 620156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(displayedValues); 621156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 622156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // year spinner range does not change based on the current date 623156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR)); 624156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR)); 625156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setWrapSelectorWheel(false); 626156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 627156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner values 628156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR)); 629156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH)); 630156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 634156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov * Updates the calendar view with the current date. 63550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 636e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void updateCalendarView() { 637156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 64150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected year. 64250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getYear() { 644156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.YEAR); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 64850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected month. 64950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMonth() { 651156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.MONTH); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 65450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 65550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected day of month. 65650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDayOfMonth() { 658156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.DAY_OF_MONTH); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6602bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu 66150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 66250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Notifies the listener, if such, for a change in the selected date. 66350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 66450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private void notifyDateChanged() { 6658a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 66650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov if (mOnDateChangedListener != null) { 667156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth()); 6682bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 6692bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 670e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson 67150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 67250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Class for managing state storing/restoring. 67350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 67450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static class SavedState extends BaseSavedState { 67550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 67650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mYear; 67750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 67850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mMonth; 67950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 68050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mDay; 68150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 68250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 68350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link DatePicker#onSaveInstanceState()} 68450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 68550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcelable superState, int year, int month, int day) { 68650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(superState); 68750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = year; 68850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = month; 68950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = day; 69050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 69150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 69250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 69350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link #CREATOR} 69450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 69550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcel in) { 69650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(in); 69750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = in.readInt(); 69850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = in.readInt(); 69950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = in.readInt(); 700e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 70150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 70250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @Override 70350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void writeToParcel(Parcel dest, int flags) { 70450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super.writeToParcel(dest, flags); 70550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mYear); 70650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mMonth); 70750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mDay); 70850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 70950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 71050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @SuppressWarnings("all") 71150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // suppress unused and hiding 71250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { 71350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 71450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState createFromParcel(Parcel in) { 71550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState(in); 71650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 71750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 71850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState[] newArray(int size) { 71950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState[size]; 72050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 72150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 722e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 723f114809031c5e5017bf69ab7a6d01024f1745fc8Svetoslav Ganov 7243fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov private void setContentDescriptions() { 7253fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov // Day 7263fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov String text = mContext.getString(R.string.date_picker_increment_day_button); 7273fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mDaySpinner.findViewById(R.id.increment).setContentDescription(text); 7283fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov text = mContext.getString(R.string.date_picker_decrement_day_button); 7293fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mDaySpinner.findViewById(R.id.decrement).setContentDescription(text); 7303fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov // Month 7313fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov text = mContext.getString(R.string.date_picker_increment_month_button); 7323fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mMonthSpinner.findViewById(R.id.increment).setContentDescription(text); 7333fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov text = mContext.getString(R.string.date_picker_decrement_month_button); 7343fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text); 7353fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov // Year 7363fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov text = mContext.getString(R.string.date_picker_increment_year_button); 7373fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mYearSpinner.findViewById(R.id.increment).setContentDescription(text); 7383fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov text = mContext.getString(R.string.date_picker_decrement_year_button); 7393fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov mYearSpinner.findViewById(R.id.decrement).setContentDescription(text); 7403fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov } 7413fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov} 742