DatePicker.java revision 8a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8
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 1950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganovimport com.android.internal.R; 2050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 26e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.text.TextUtils; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.DateFormat; 28dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport android.text.format.DateUtils; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 30e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport android.util.Log; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 338a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 34cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganovimport android.widget.NumberPicker.OnValueChangeListener; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.text.ParseException; 3703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat; 38156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganovimport java.util.Arrays; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 40dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale; 41e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.util.TimeZone; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 44e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * This class is a widget for selecting a date. The date can be selected by a 45e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * year, month, and day spinners or a {@link CalendarView}. The set of spinners 46e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * and the calendar view are automatically synchronized. The client can 47e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * customize whether only the spinners, or only the calendar view, or both to be 48e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * displayed. Also the minimal and maximal date from which dates to be selected 49e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * can be customized. 5050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p> 519a143e6641fa4a5942e7341007d916601402e8dfDirk Dougherty * See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date 529a143e6641fa4a5942e7341007d916601402e8dfDirk Dougherty * Picker tutorial</a>. 5350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p> 54e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}. 56e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p> 57e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 58e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear 59e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear 60e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate 61e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate 62e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown 63e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String LOG_TAG = DatePicker.class.getSimpleName(); 69e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String DATE_FORMAT = "MM/dd/yyyy"; 71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DEFAULT_START_YEAR = 1900; 73dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 7450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static final int DEFAULT_END_YEAR = 2100; 75dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 76e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true; 77e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 78e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_SPINNERS_SHOWN = true; 7950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 8025f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private static final boolean DEFAULT_ENABLED_STATE = true; 8125f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov 82e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mDaySpinner; 8350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 84e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final LinearLayout mSpinners; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mMonthSpinner; 87e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 88e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mYearSpinner; 89e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 90e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final CalendarView mCalendarView; 9150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDateChangedListener mOnDateChangedListener; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private Locale mMonthLocale; 9550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 96e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final Calendar mTempDate = Calendar.getInstance(); 9750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 98e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final int mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1; 9950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 10050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final String[] mShortMonths = new String[mNumberOfMonths]; 101dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 102e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT); 103e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 104e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final Calendar mMinDate = Calendar.getInstance(); 105e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 106e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final Calendar mMaxDate = Calendar.getInstance(); 107e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 108e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final Calendar mCurrentDate = Calendar.getInstance(); 109e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 11025f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private boolean mIsEnabled = DEFAULT_ENABLED_STATE; 11151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 113e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * The callback used to indicate the user changes\d the date. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDateChangedListener { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 118e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Called upon a date change. 119e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view associated with this listener. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The year that was set. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param monthOfYear The month that was set (0-11) for compatibility 12350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * with {@link java.util.Calendar}. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The day of the month that was set. 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs) { 1344243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov this(context, attrs, R.attr.datePickerStyle); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs, int defStyle) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1404243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker, 1414243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov defStyle, 0); 142e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown, 143e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov DEFAULT_SPINNERS_SHOWN); 144e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean calendarViewShown = attributesArray.getBoolean( 145e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN); 1464243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear, 1474243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov DEFAULT_START_YEAR); 148e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); 149e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String minDate = attributesArray.getString(R.styleable.DatePicker_minDate); 150e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate); 1514243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_layout, 1524243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov R.layout.date_picker); 153e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov attributesArray.recycle(); 154e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 15550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov LayoutInflater inflater = (LayoutInflater) context 15650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 1574243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov inflater.inflate(layoutResourceId, this, true); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 159cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganov OnValueChangeListener onChangeListener = new OnValueChangeListener() { 160e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 161156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); 162156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // take care of wrapping of days and months to update greater fields 163156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (picker == mDaySpinner) { 164156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH); 165156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == maxDayOfMonth && newVal == 1) { 166156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, 1); 167156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 1 && newVal == maxDayOfMonth) { 168156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, -1); 169156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 170156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal); 171156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 172156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mMonthSpinner) { 173156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == 11 && newVal == 0) { 174156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, 1); 175156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 0 && newVal == 11) { 176156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, -1); 177156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 178156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, newVal - oldVal); 179156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 180156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mYearSpinner) { 181156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.set(Calendar.YEAR, newVal); 182156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 183156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov throw new IllegalArgumentException(); 184156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 185156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // now set the date to the adjusted one 186156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH), 187156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.get(Calendar.DAY_OF_MONTH)); 18858f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 18958f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 190156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 1935fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 194e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners = (LinearLayout) findViewById(R.id.pickers); 195e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 196e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // calendar view day-picker 197e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView = (CalendarView) findViewById(R.id.calendar_view); 198e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { 199e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) { 200156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, monthDay); 20158f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 202156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 20328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 20428104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov }); 20528104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 20650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // day 207e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner = (NumberPicker) findViewById(R.id.day); 208e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); 209e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnLongPressUpdateInterval(100); 210e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnValueChangedListener(onChangeListener); 2115fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 21250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // month 213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner = (NumberPicker) findViewById(R.id.month); 214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMinValue(0); 215e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMaxValue(mNumberOfMonths - 1); 216e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setDisplayedValues(getShortMonths()); 217e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnLongPressUpdateInterval(200); 218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnValueChangedListener(onChangeListener); 21950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 22050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // year 221e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner = (NumberPicker) findViewById(R.id.year); 222e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnLongPressUpdateInterval(100); 223e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnValueChangedListener(onChangeListener); 224e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 225e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show only what the user required but make sure we 226e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show something and the spinners have higher priority 227e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!spinnersShown && !calendarViewShown) { 228e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(true); 229e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else { 230e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(spinnersShown); 231e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setCalendarViewShown(calendarViewShown); 232e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 233e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // set the min date giving priority of the minDate over startYear 234e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.clear(); 235e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!TextUtils.isEmpty(minDate)) { 236e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!parseDate(minDate, mTempDate)) { 237e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(startYear, 0, 1); 238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 239e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else { 240e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(startYear, 0, 1); 241e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 242e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMinDate.clear(); 243e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setMinDate(mTempDate.getTimeInMillis()); 244e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 245e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // set the max date giving priority of the minDate over startYear 246e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.clear(); 247e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!TextUtils.isEmpty(maxDate)) { 248e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!parseDate(maxDate, mTempDate)) { 249e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(endYear, 11, 31); 250e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 251e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else { 252e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(endYear, 11, 31); 253e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 254e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMaxDate.clear(); 255e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setMaxDate(mTempDate.getTimeInMillis()); 256e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 257e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // initialize to current date 258e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(System.currentTimeMillis()); 259e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate 260e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov .get(Calendar.DAY_OF_MONTH), null); 261e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 262e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 263e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // re-order the number spinners to match the current date format 264e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov reorderSpinners(); 265e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 266e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 267e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 268e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the minimal date supported by this {@link DatePicker} in 269e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 270e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 271e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 272e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default minimal date is 01/01/1900. 273e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 274e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 275e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The minimal supported date. 276e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 277e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMinDate() { 278e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMinDate(); 279e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 280e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 281e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 282e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the minimal date supported by this {@link NumberPicker} in 283e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 284e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 285e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 286e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param minDate The minimal supported date. 287e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 288e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMinDate(long minDate) { 289e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(minDate); 290e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR) 291e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) { 292e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 293e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 294e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMinDate.setTimeInMillis(minDate); 295e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMinDate(minDate); 296156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 297156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 298156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 299156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 300156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 30328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov /** 304e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the maximal date supported by this {@link DatePicker} in 305e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 306e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 307e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 308e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default maximal date is 12/31/2100. 30928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * <p> 31028104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * 311e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The maximal supported date. 312e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 313e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMaxDate() { 314e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMaxDate(); 315e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 316e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 317e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 318e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the maximal date supported by this {@link DatePicker} in 319e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 320e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 321e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 322e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param maxDate The maximal supported date. 32328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov */ 324e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMaxDate(long maxDate) { 325e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(maxDate); 326e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR) 327e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) { 328e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 32928104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 330e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMaxDate.setTimeInMillis(maxDate); 331e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMaxDate(maxDate); 332156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.after(mMaxDate)) { 333156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 334156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 335156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 336156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 33728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 33828104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setEnabled(boolean enabled) { 34151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov if (mIsEnabled == enabled) { 34251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return; 34351c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setEnabled(enabled); 345e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setEnabled(enabled); 346e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setEnabled(enabled); 347e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setEnabled(enabled); 348e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setEnabled(enabled); 34951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov mIsEnabled = enabled; 35051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 35151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 35251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov @Override 35351c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov public boolean isEnabled() { 35451c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return mIsEnabled; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3578a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov @Override 3588a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3598a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY 3608a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov | DateUtils.FORMAT_SHOW_YEAR; 3618a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov String selectedDateUtterance = DateUtils.formatDateTime(mContext, 3628a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov mCurrentDate.getTimeInMillis(), flags); 3638a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov event.getText().add(selectedDateUtterance); 3648a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov return true; 3658a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov } 3668a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov 36750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 368e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the {@link CalendarView} is shown. 369e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 370e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the calendar view is shown. 371e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 372e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getCalendarViewShown() { 373e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.isShown(); 374e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 375e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 376e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 377e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the {@link CalendarView} is shown. 378e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 379e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the calendar view is to be shown. 380e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 381e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setCalendarViewShown(boolean shown) { 382e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setVisibility(shown ? VISIBLE : GONE); 383e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 384e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 385e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 386e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the spinners are shown. 387e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 388e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the spinners are shown. 38950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 390e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getSpinnersShown() { 391e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mSpinners.isShown(); 392e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 393e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 394e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 395e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the spinners are shown. 396e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 397e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the spinners are to be shown. 398e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 399e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setSpinnersShown(boolean shown) { 400e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners.setVisibility(shown ? VISIBLE : GONE); 401e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 402e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 403e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 404e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Reorders the spinners according to the date format in the current 405e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link Locale}. 406e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 407e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void reorderSpinners() { 40803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer java.text.DateFormat format; 40903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer String order; 41003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 41103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer /* 41250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * If the user is in a locale where the medium date format is still 41350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * numeric (Japanese and Czech, for example), respect the date format 41450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * order setting. Otherwise, use the order that the locale says is 41550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * appropriate for a spelled-out date. 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 41703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 41850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov if (getShortMonths()[0].startsWith("1")) { 41903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer format = DateFormat.getDateFormat(getContext()); 42003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } else { 42103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer format = DateFormat.getMediumDateFormat(getContext()); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 42403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (format instanceof SimpleDateFormat) { 42503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer order = ((SimpleDateFormat) format).toPattern(); 42603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } else { 42703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer // Shouldn't happen, but just in case. 42803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer order = new String(DateFormat.getDateFormatOrder(getContext())); 42903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 43003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 43150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /* 432e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Remove the 3 spinners from their parent and then add them back in the 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * required order. 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 435e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov LinearLayout parent = mSpinners; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent.removeAllViews(); 43703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 43803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer boolean quoted = false; 43903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer boolean didDay = false, didMonth = false, didYear = false; 44003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 44103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer for (int i = 0; i < order.length(); i++) { 44203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer char c = order.charAt(i); 44303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 44403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (c == '\'') { 44503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer quoted = !quoted; 44603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 44703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 44803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (!quoted) { 44903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (c == DateFormat.DATE && !didDay) { 450e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mDaySpinner); 45103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer didDay = true; 45203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) { 453e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mMonthSpinner); 45403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer didMonth = true; 45503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } else if (c == DateFormat.YEAR && !didYear) { 456e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mYearSpinner); 45703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer didYear = true; 45803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 46203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer // Shouldn't happen, but just in case. 46303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (!didMonth) { 464e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mMonthSpinner); 46503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 46603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (!didDay) { 467e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mDaySpinner); 46803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 46903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (!didYear) { 470e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov parent.addView(mYearSpinner); 47103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 47550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Updates the current date. 47650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 47750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param year The year. 47850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param month The month which is <strong>starting from zero</strong>. 47950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param dayOfMonth The day of the month. 48050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 48150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void updateDate(int year, int month, int dayOfMonth) { 482156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (!isNewDate(year, month, dayOfMonth)) { 483156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return; 484dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 485156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, dayOfMonth); 48658f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 48758f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 488156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 489dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 490dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 49150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // Override so we are in complete control of save / restore for this widget. 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchThawSelfOnly(container); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Parcelable onSaveInstanceState() { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcelable superState = super.onSaveInstanceState(); 500156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return new SavedState(superState, getYear(), getMonth(), getDayOfMonth()); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onRestoreInstanceState(Parcelable state) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState ss = (SavedState) state; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onRestoreInstanceState(ss.getSuperState()); 507156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(ss.mYear, ss.mMonth, ss.mDay); 50858f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 50958f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 51350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Initialize the state. If the provided values designate an inconsistent 514e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * date the values are normalized before updating the spinners. 51550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The initial year. 51750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param monthOfYear The initial month <strong>starting from zero</strong>. 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The initial day of the month. 51950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param onDateChangedListener How user is notified date is changed by 52050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * user, can be null. 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void init(int year, int monthOfYear, int dayOfMonth, 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnDateChangedListener onDateChangedListener) { 524156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, monthOfYear, dayOfMonth); 52558f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 52658f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 5272f136a874d240cc7e85e8de9c7644a7daa9532daSvetoslav Ganov mOnDateChangedListener = onDateChangedListener; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 531e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Parses the given <code>date</code> and in case of success sets the result 532e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * to the <code>outDate</code>. 533a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov * 534e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the date was parsed. 535a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov */ 536e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private boolean parseDate(String date, Calendar outDate) { 537e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov try { 538e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov outDate.setTime(mDateFormat.parse(date)); 539e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return true; 540e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } catch (ParseException e) { 541e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT); 542e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return false; 543e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 544a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 545a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov 546a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov /** 547a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov * @return The short month abbreviations. 548a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov */ 549a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov private String[] getShortMonths() { 550a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov final Locale currentLocale = Locale.getDefault(); 551a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov if (currentLocale.equals(mMonthLocale)) { 552a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov return mShortMonths; 553a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } else { 554a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov for (int i = 0; i < mNumberOfMonths; i++) { 555a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i, 556a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov DateUtils.LENGTH_MEDIUM); 557a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 558a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov mMonthLocale = currentLocale; 559a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov return mShortMonths; 560a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 561a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 562a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov 563156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private boolean isNewDate(int year, int month, int dayOfMonth) { 564156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return (mCurrentDate.get(Calendar.YEAR) != year 565156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.MONTH) != dayOfMonth 566156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month); 567156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 568e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 569156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void setDate(int year, int month, int dayOfMonth) { 570156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.set(year, month, dayOfMonth); 571e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 572e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 573e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else if (mCurrentDate.after(mMaxDate)) { 574e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 575e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 576e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 577e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 578156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void updateSpinners() { 579156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner ranges respecting the min and max dates 580156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.equals(mMinDate)) { 581156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 582156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 583156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 584156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 585156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH)); 586156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH)); 587156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 588156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (mCurrentDate.equals(mMaxDate)) { 589156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH)); 590156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 591156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 592156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 593156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH)); 594156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH)); 595156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 596156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 597156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(1); 598156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 599156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(true); 600156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 601156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(0); 602156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(11); 603156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(true); 604e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 605e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 606156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // make sure the month names are a zero based array 607156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // with the months in the month spinner 608156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov String[] displayedValues = Arrays.copyOfRange(getShortMonths(), 609156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1); 610156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(displayedValues); 611156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 612156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // year spinner range does not change based on the current date 613156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR)); 614156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR)); 615156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setWrapSelectorWheel(false); 616156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 617156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner values 618156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR)); 619156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH)); 620156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 624156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov * Updates the calendar view with the current date. 62550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 626e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void updateCalendarView() { 627156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 63150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected year. 63250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getYear() { 634156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.YEAR); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 63850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected month. 63950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMonth() { 641156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.MONTH); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 64550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected day of month. 64650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDayOfMonth() { 648156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.DAY_OF_MONTH); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6502bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu 65150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 65250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Notifies the listener, if such, for a change in the selected date. 65350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 65450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private void notifyDateChanged() { 6558a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 65650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov if (mOnDateChangedListener != null) { 657156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth()); 6582bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 6592bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 660e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson 66150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 66250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Class for managing state storing/restoring. 66350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 66450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static class SavedState extends BaseSavedState { 66550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 66650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mYear; 66750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 66850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mMonth; 66950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 67050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mDay; 67150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 67250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 67350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link DatePicker#onSaveInstanceState()} 67450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 67550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcelable superState, int year, int month, int day) { 67650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(superState); 67750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = year; 67850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = month; 67950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = day; 68050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 68150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 68250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 68350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link #CREATOR} 68450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 68550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcel in) { 68650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(in); 68750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = in.readInt(); 68850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = in.readInt(); 68950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = in.readInt(); 690e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 69150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 69250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @Override 69350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void writeToParcel(Parcel dest, int flags) { 69450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super.writeToParcel(dest, flags); 69550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mYear); 69650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mMonth); 69750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mDay); 69850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 69950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 70050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @SuppressWarnings("all") 70150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // suppress unused and hiding 70250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { 70350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 70450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState createFromParcel(Parcel in) { 70550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState(in); 70650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 70750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 70850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState[] newArray(int size) { 70950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState[size]; 71050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 71150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 712e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 714