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; 26e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kimimport android.text.InputType; 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; 33d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganovimport android.view.View; 348a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 358a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 36a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganovimport android.view.inputmethod.EditorInfo; 376304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganovimport android.view.inputmethod.InputMethodManager; 38cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganovimport android.widget.NumberPicker.OnValueChangeListener; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganovimport com.android.internal.R; 41f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 42949e9df25bccb736675f950591d3a286ae4052fcElliott Hughesimport java.text.DateFormatSymbols; 43e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.text.ParseException; 4403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat; 45156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganovimport java.util.Arrays; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 47dddda8d188408ff18935b1b0e15a00fe012a03daKenny Rootimport java.util.Locale; 48e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganovimport java.util.TimeZone; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50659f145278ffd85f934a435dbec47ead685caf59Elliott Hughesimport libcore.icu.ICU; 51659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 53e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * This class is a widget for selecting a date. The date can be selected by a 54e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * year, month, and day spinners or a {@link CalendarView}. The set of spinners 55e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * and the calendar view are automatically synchronized. The client can 56e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * customize whether only the spinners, or only the calendar view, or both to be 57e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * displayed. Also the minimal and maximal date from which dates to be selected 58e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * can be customized. 5950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * <p> 604c359b76f9a030f92a302ba74a528faa170bad4eScott Main * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> 614c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide. 6250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * </p> 63e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}. 65e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * </p> 66e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 67e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_startYear 68e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_endYear 69e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_maxDate 70e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_minDate 71e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_spinnersShown 72e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @attr ref android.R.styleable#DatePicker_calendarViewShown 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 77e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String LOG_TAG = DatePicker.class.getSimpleName(); 78e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 79e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final String DATE_FORMAT = "MM/dd/yyyy"; 80e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DEFAULT_START_YEAR = 1900; 82dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 8350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static final int DEFAULT_END_YEAR = 2100; 84dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 85e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true; 86e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 87e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private static final boolean DEFAULT_SPINNERS_SHOWN = true; 8850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 8925f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private static final boolean DEFAULT_ENABLED_STATE = true; 9025f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov 91e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final LinearLayout mSpinners; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov private final NumberPicker mDaySpinner; 94a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov 95e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mMonthSpinner; 96e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 97e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final NumberPicker mYearSpinner; 98e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 996304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov private final EditText mDaySpinnerInput; 1006304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov 1016304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov private final EditText mMonthSpinnerInput; 1026304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov 1036304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov private final EditText mYearSpinnerInput; 1046304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov 105e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private final CalendarView mCalendarView; 10650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 107f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Locale mCurrentLocale; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private OnDateChangedListener mOnDateChangedListener; 11050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 111f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private String[] mShortMonths; 11250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 113f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT); 11450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 115f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private int mNumberOfMonths; 116dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 117f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mTempDate; 118e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 119f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mMinDate; 120e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 121f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mMaxDate; 122e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 123f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar mCurrentDate; 124e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 12525f84f323c607bbd9133432fd789ba29b2dcd4d4Svetoslav Ganov private boolean mIsEnabled = DEFAULT_ENABLED_STATE; 12651c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 128e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * The callback used to indicate the user changes\d the date. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDateChangedListener { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 133e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Called upon a date change. 134e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view associated with this listener. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The year that was set. 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param monthOfYear The month that was set (0-11) for compatibility 13850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * with {@link java.util.Calendar}. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The day of the month that was set. 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs) { 1494243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov this(context, attrs, R.attr.datePickerStyle); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DatePicker(Context context, AttributeSet attrs, int defStyle) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 155f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov // initialization based on locale 156f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov setCurrentLocale(Locale.getDefault()); 157f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 1584243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker, 1594243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov defStyle, 0); 160e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown, 161e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov DEFAULT_SPINNERS_SHOWN); 162e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov boolean calendarViewShown = attributesArray.getBoolean( 163e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN); 1644243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear, 1654243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov DEFAULT_START_YEAR); 166e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); 167e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String minDate = attributesArray.getString(R.styleable.DatePicker_minDate); 168e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate); 169c49a8be0d2aee5a3d1ff50015a0c0758b0988cfbSvetoslav Ganov int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_internalLayout, 1704243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov R.layout.date_picker); 171e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov attributesArray.recycle(); 172e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 17350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov LayoutInflater inflater = (LayoutInflater) context 17450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 1754243dc394d89a93cb207efa36e9755c2424d688bSvetoslav Ganov inflater.inflate(layoutResourceId, this, true); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 177cedc446684e94c9971c38c3206f1f224314bda2aSvetoslav Ganov OnValueChangeListener onChangeListener = new OnValueChangeListener() { 178e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 1796304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov updateInputState(); 180156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); 181156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // take care of wrapping of days and months to update greater fields 182156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (picker == mDaySpinner) { 183156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH); 184156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == maxDayOfMonth && newVal == 1) { 185156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, 1); 186156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 1 && newVal == maxDayOfMonth) { 187156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, -1); 188156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 189156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal); 190156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 191156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mMonthSpinner) { 192156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (oldVal == 11 && newVal == 0) { 193156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, 1); 194156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (oldVal == 0 && newVal == 11) { 195156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, -1); 196156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 197156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.add(Calendar.MONTH, newVal - oldVal); 198156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 199156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (picker == mYearSpinner) { 200156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.set(Calendar.YEAR, newVal); 201156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 202156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov throw new IllegalArgumentException(); 203156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 204156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // now set the date to the adjusted one 205156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH), 206156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mTempDate.get(Calendar.DAY_OF_MONTH)); 20758f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 20858f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 209156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 2125fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 213e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners = (LinearLayout) findViewById(R.id.pickers); 214e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 215e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // calendar view day-picker 216e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView = (CalendarView) findViewById(R.id.calendar_view); 217e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { 218e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) { 219156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, monthDay); 22058f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 221156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 22228104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 22328104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov }); 22428104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 22550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // day 226e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner = (NumberPicker) findViewById(R.id.day); 227d88e3054d08b1f821bb2e27b2647aa16a60d8742Fabrice Di Meglio mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); 228e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnLongPressUpdateInterval(100); 229e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setOnValueChangedListener(onChangeListener); 2306304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input); 2315fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer 23250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // month 233e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner = (NumberPicker) findViewById(R.id.month); 234e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMinValue(0); 235e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setMaxValue(mNumberOfMonths - 1); 236f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMonthSpinner.setDisplayedValues(mShortMonths); 237e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnLongPressUpdateInterval(200); 238e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setOnValueChangedListener(onChangeListener); 2396304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input); 24050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 24150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // year 242e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner = (NumberPicker) findViewById(R.id.year); 243e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnLongPressUpdateInterval(100); 244e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setOnValueChangedListener(onChangeListener); 2456304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input); 246e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 247e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show only what the user required but make sure we 248e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // show something and the spinners have higher priority 249e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (!spinnersShown && !calendarViewShown) { 250e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(true); 251e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else { 252e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setSpinnersShown(spinnersShown); 253e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov setCalendarViewShown(calendarViewShown); 25413427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } 255e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 25613427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // set the min date giving priority of the minDate over startYear 25713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.clear(); 25813427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!TextUtils.isEmpty(minDate)) { 25913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!parseDate(minDate, mTempDate)) { 260e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(startYear, 0, 1); 261e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 26213427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } else { 26313427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.set(startYear, 0, 1); 26413427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } 26513427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov setMinDate(mTempDate.getTimeInMillis()); 26613427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov 26713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // set the max date giving priority of the maxDate over endYear 26813427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.clear(); 26913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!TextUtils.isEmpty(maxDate)) { 27013427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov if (!parseDate(maxDate, mTempDate)) { 271e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.set(endYear, 11, 31); 272e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 27313427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov } else { 27413427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mTempDate.set(endYear, 11, 31); 275e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 27613427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov setMaxDate(mTempDate.getTimeInMillis()); 27713427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov 27813427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov // initialize to current date 27913427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov mCurrentDate.setTimeInMillis(System.currentTimeMillis()); 28013427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate 28113427a04de835677f9e5f727298f168b88faa562Svetoslav Ganov .get(Calendar.DAY_OF_MONTH), null); 282e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 283e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov // re-order the number spinners to match the current date format 284e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov reorderSpinners(); 2853fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov 2864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov // accessibility 287d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov setContentDescriptions(); 2884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 2894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov // If not explicitly specified this view is important for accessibility. 2904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { 2914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); 2924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 293e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 294e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 295e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 296e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the minimal date supported by this {@link DatePicker} in 297e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 298e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 299e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 300e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default minimal date is 01/01/1900. 301e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 302e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 303e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The minimal supported date. 304e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 305e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMinDate() { 306e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMinDate(); 307e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 308e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 309e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 310e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the minimal date supported by this {@link NumberPicker} in 311e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 312e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 313e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 314e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param minDate The minimal supported date. 315e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 316e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMinDate(long minDate) { 317e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(minDate); 318e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR) 319e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) { 320e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 321e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 322e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMinDate.setTimeInMillis(minDate); 323e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMinDate(minDate); 324156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 325156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 326156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 327156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 328156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 33128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov /** 332e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets the maximal date supported by this {@link DatePicker} in 333e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 334e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 335e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * <p> 336e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Note: The default maximal date is 12/31/2100. 33728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * <p> 33828104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov * 339e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return The maximal supported date. 340e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 341e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public long getMaxDate() { 342e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mCalendarView.getMaxDate(); 343e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 344e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 345e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 346e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets the maximal date supported by this {@link DatePicker} in 347e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * milliseconds since January 1, 1970 00:00:00 in 348e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * {@link TimeZone#getDefault()} time zone. 349e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 350e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param maxDate The maximal supported date. 35128104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov */ 352e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setMaxDate(long maxDate) { 353e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mTempDate.setTimeInMillis(maxDate); 354e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR) 355e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) { 356e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return; 35728104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 358e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMaxDate.setTimeInMillis(maxDate); 359e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setMaxDate(maxDate); 360156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.after(mMaxDate)) { 361156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 362156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateCalendarView(); 363156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 364156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov updateSpinners(); 36528104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov } 36628104e1de5595a22a6987181b13ddeb192739afdSvetoslav Ganov 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setEnabled(boolean enabled) { 36951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov if (mIsEnabled == enabled) { 37051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return; 37151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setEnabled(enabled); 373e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mDaySpinner.setEnabled(enabled); 374e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mMonthSpinner.setEnabled(enabled); 375e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mYearSpinner.setEnabled(enabled); 376e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setEnabled(enabled); 37751c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov mIsEnabled = enabled; 37851c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov } 37951c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov 38051c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov @Override 38151c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov public boolean isEnabled() { 38251c52edad7d40697d7fb2a091f850506fa897643Svetoslav Ganov return mIsEnabled; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3858a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov @Override 3863fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3873fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov onPopulateAccessibilityEvent(event); 3883fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov return true; 3893fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov } 3903fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov 3913fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov @Override 392736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 393736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov super.onPopulateAccessibilityEvent(event); 394736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 3953fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; 3968a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov String selectedDateUtterance = DateUtils.formatDateTime(mContext, 3978a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov mCurrentDate.getTimeInMillis(), flags); 3988a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov event.getText().add(selectedDateUtterance); 3998a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov } 4008a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov 401f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov @Override 4028a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 4038a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 4048a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(DatePicker.class.getName()); 4058a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 4068a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 4078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 4088a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 4098a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 4108a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(DatePicker.class.getName()); 4118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 4128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 4138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 414f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov protected void onConfigurationChanged(Configuration newConfig) { 415f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov super.onConfigurationChanged(newConfig); 416f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov setCurrentLocale(newConfig.locale); 417f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 418f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 41950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 420e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the {@link CalendarView} is shown. 421e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 422e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the calendar view is shown. 4235f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @see #getCalendarView() 424e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 425e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getCalendarViewShown() { 426e10837f444c3da40a50a269e696afac63729bce3Svetoslav return (mCalendarView.getVisibility() == View.VISIBLE); 427e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 428e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 429e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 4305f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * Gets the {@link CalendarView}. 4315f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * 4325f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @return The calendar view. 4335f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov * @see #getCalendarViewShown() 4345f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov */ 4355f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov public CalendarView getCalendarView () { 4365f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov return mCalendarView; 4375f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov } 4385f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov 4395f3f6ce154ca1a0075f8ca13872d74f935acbe3dSvetoslav Ganov /** 440e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the {@link CalendarView} is shown. 441e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 442e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the calendar view is to be shown. 443e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 444e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setCalendarViewShown(boolean shown) { 445e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCalendarView.setVisibility(shown ? VISIBLE : GONE); 446e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 447e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 448e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 449e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Gets whether the spinners are shown. 450e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 451e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the spinners are shown. 45250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 453e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public boolean getSpinnersShown() { 454e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return mSpinners.isShown(); 455e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 456e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 457e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 458e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Sets whether the spinners are shown. 459e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * 460e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @param shown True if the spinners are to be shown. 461e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 462e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov public void setSpinnersShown(boolean shown) { 463e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mSpinners.setVisibility(shown ? VISIBLE : GONE); 464e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 465e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 466e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov /** 467f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * Sets the current locale. 468f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * 469f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param locale The current locale. 470f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov */ 471f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private void setCurrentLocale(Locale locale) { 472f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov if (locale.equals(mCurrentLocale)) { 473f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return; 474f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 475f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 476f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mCurrentLocale = locale; 477f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 478f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mTempDate = getCalendarForLocale(mTempDate, locale); 479f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMinDate = getCalendarForLocale(mMinDate, locale); 480f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mMaxDate = getCalendarForLocale(mMaxDate, locale); 481f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mCurrentDate = getCalendarForLocale(mCurrentDate, locale); 482f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 483f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1; 484949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes mShortMonths = new DateFormatSymbols().getShortMonths(); 485949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes 486949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes if (usingNumericMonths()) { 487949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes // We're in a locale where a date should either be all-numeric, or all-text. 488949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes // All-text would require custom NumberPicker formatters for day and year. 489949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes mShortMonths = new String[mNumberOfMonths]; 490949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes for (int i = 0; i < mNumberOfMonths; ++i) { 491949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes mShortMonths[i] = String.format("%d", i + 1); 492949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes } 493f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 494f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 495f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 496f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov /** 497949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes * Tests whether the current locale is one where there are no real month names, 498949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes * such as Chinese, Japanese, or Korean locales. 499949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes */ 500949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes private boolean usingNumericMonths() { 501949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0)); 502949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes } 503949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes 504949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes /** 505f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * Gets a calendar for locale bootstrapped with the value of a given calendar. 506f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * 507f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param oldCalendar The old calendar. 508f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov * @param locale The locale. 509f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov */ 510f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) { 511f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov if (oldCalendar == null) { 512f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return Calendar.getInstance(locale); 513f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } else { 514f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov final long currentTimeMillis = oldCalendar.getTimeInMillis(); 515f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov Calendar newCalendar = Calendar.getInstance(locale); 516f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov newCalendar.setTimeInMillis(currentTimeMillis); 517f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov return newCalendar; 518f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 519f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov } 520f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov 521f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov /** 522f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * Reorders the spinners according to the date format that is 523f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * explicitly set by the user and if no such is set fall back 524f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov * to the current locale's default format. 525e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov */ 526e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void reorderSpinners() { 527f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.removeAllViews(); 528659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes // We use numeric spinners for year and day, but textual months. Ask icu4c what 529659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes // order the user's locale uses for that combination. http://b/7207103. 530659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString()); 531659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes char[] order = ICU.getDateFormatOrder(pattern); 532a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov final int spinnerCount = order.length; 533a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov for (int i = 0; i < spinnerCount; i++) { 534f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov switch (order[i]) { 535659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes case 'd': 536f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mDaySpinner); 537a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov setImeOptions(mDaySpinner, spinnerCount, i); 538f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 539659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes case 'M': 540f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mMonthSpinner); 541a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov setImeOptions(mMonthSpinner, spinnerCount, i); 542f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 543659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes case 'y': 544f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov mSpinners.addView(mYearSpinner); 545a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov setImeOptions(mYearSpinner, spinnerCount, i); 546f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov break; 547f583dd37643f495642cd64e9b8e6a0a9e0836ff1Svetoslav Ganov default: 548659f145278ffd85f934a435dbec47ead685caf59Elliott Hughes throw new IllegalArgumentException(Arrays.toString(order)); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 55450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Updates the current date. 55550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 55650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param year The year. 55750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param month The month which is <strong>starting from zero</strong>. 55850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param dayOfMonth The day of the month. 55950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 56050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void updateDate(int year, int month, int dayOfMonth) { 561156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (!isNewDate(year, month, dayOfMonth)) { 562156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return; 563dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 564156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, month, dayOfMonth); 56558f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 56658f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 567156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov notifyDateChanged(); 568dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root } 569dddda8d188408ff18935b1b0e15a00fe012a03daKenny Root 57050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // Override so we are in complete control of save / restore for this widget. 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchThawSelfOnly(container); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Parcelable onSaveInstanceState() { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcelable superState = super.onSaveInstanceState(); 579156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return new SavedState(superState, getYear(), getMonth(), getDayOfMonth()); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onRestoreInstanceState(Parcelable state) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState ss = (SavedState) state; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onRestoreInstanceState(ss.getSuperState()); 586156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(ss.mYear, ss.mMonth, ss.mDay); 58758f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 58858f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 59250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Initialize the state. If the provided values designate an inconsistent 593e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * date the values are normalized before updating the spinners. 59450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year The initial year. 59650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param monthOfYear The initial month <strong>starting from zero</strong>. 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dayOfMonth The initial day of the month. 59850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param onDateChangedListener How user is notified date is changed by 59950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * user, can be null. 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void init(int year, int monthOfYear, int dayOfMonth, 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnDateChangedListener onDateChangedListener) { 603156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov setDate(year, monthOfYear, dayOfMonth); 60458f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateSpinners(); 60558f51255eb20f9c4d16c11554f372ff92d45fcc7Svetoslav Ganov updateCalendarView(); 6062f136a874d240cc7e85e8de9c7644a7daa9532daSvetoslav Ganov mOnDateChangedListener = onDateChangedListener; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 610e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * Parses the given <code>date</code> and in case of success sets the result 611e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * to the <code>outDate</code>. 612a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov * 613e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov * @return True if the date was parsed. 614a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov */ 615e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private boolean parseDate(String date, Calendar outDate) { 616e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov try { 617e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov outDate.setTime(mDateFormat.parse(date)); 618e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return true; 619e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } catch (ParseException e) { 620e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT); 621e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov return false; 622e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 623a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov } 624a911d4a2b1be7e9ea909a579167826e4a5bac1a3Svetoslav Ganov 625156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private boolean isNewDate(int year, int month, int dayOfMonth) { 626156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return (mCurrentDate.get(Calendar.YEAR) != year 627156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.MONTH) != dayOfMonth 628156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month); 629156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } 630e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 631156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void setDate(int year, int month, int dayOfMonth) { 632156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCurrentDate.set(year, month, dayOfMonth); 633e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov if (mCurrentDate.before(mMinDate)) { 634e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); 635e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } else if (mCurrentDate.after(mMaxDate)) { 636e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); 637e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 638e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 639e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 640156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov private void updateSpinners() { 641156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner ranges respecting the min and max dates 642156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov if (mCurrentDate.equals(mMinDate)) { 643156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 644156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 645156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 646156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 647156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH)); 648156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH)); 649156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 650156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else if (mCurrentDate.equals(mMaxDate)) { 651156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH)); 652156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 653156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(false); 654156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 655156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH)); 656156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH)); 657156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(false); 658156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov } else { 659156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMinValue(1); 660156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH)); 661156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setWrapSelectorWheel(true); 662156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(null); 663156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMinValue(0); 664156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setMaxValue(11); 665156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setWrapSelectorWheel(true); 666e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov } 667e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov 668156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // make sure the month names are a zero based array 669156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // with the months in the month spinner 670f5926962cc665d4a2e6464f9ba9e3e9788496a6fSvetoslav Ganov String[] displayedValues = Arrays.copyOfRange(mShortMonths, 671156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1); 672156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setDisplayedValues(displayedValues); 673156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 674156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // year spinner range does not change based on the current date 675156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR)); 676156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR)); 677156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setWrapSelectorWheel(false); 678156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov 679156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov // set the spinner values 680156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR)); 681156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH)); 682156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH)); 683e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim 684949e9df25bccb736675f950591d3a286ae4052fcElliott Hughes if (usingNumericMonths()) { 685e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER); 686e9a74a1a31f82391d44840aa17293021fcab6837Hyejin Kim } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 690156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov * Updates the calendar view with the current date. 69150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 692e9730bf3d2dcbea1879f24c18aaf9810ac57084cSvetoslav Ganov private void updateCalendarView() { 693156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 69650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 69750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected year. 69850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getYear() { 700156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.YEAR); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 70450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected month. 70550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMonth() { 707156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.MONTH); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 71150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The selected day of month. 71250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDayOfMonth() { 714156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov return mCurrentDate.get(Calendar.DAY_OF_MONTH); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7162bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu 71750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 71850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Notifies the listener, if such, for a change in the selected date. 71950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 72050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private void notifyDateChanged() { 7218a2a89588c3889b999a8fffa2d7c7a5c3ce25eb8Svetoslav Ganov sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 72250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov if (mOnDateChangedListener != null) { 723156f20919b3d5f298f8851215adbf65f8b4dc61bSvetoslav Ganov mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth()); 7242bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 7252bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu } 726e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson 72750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 728a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov * Sets the IME options for a spinner based on its ordering. 729a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov * 730a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov * @param spinner The spinner. 731a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov * @param spinnerCount The total spinner count. 732a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov * @param spinnerIndex The index of the given spinner. 733a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov */ 734a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) { 735a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov final int imeOptions; 736a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov if (spinnerIndex < spinnerCount - 1) { 737a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov imeOptions = EditorInfo.IME_ACTION_NEXT; 738a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov } else { 739a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov imeOptions = EditorInfo.IME_ACTION_DONE; 740a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov } 741a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input); 742a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov input.setImeOptions(imeOptions); 743a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov } 744a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov 745a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov private void setContentDescriptions() { 746a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov // Day 747d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mDaySpinner, R.id.increment, 748d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_increment_day_button); 749d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mDaySpinner, R.id.decrement, 750d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_decrement_day_button); 751a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov // Month 752d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mMonthSpinner, R.id.increment, 753d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_increment_month_button); 754d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mMonthSpinner, R.id.decrement, 755d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_decrement_month_button); 756a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov // Year 757d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mYearSpinner, R.id.increment, 758d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_increment_year_button); 759d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov trySetContentDescription(mYearSpinner, R.id.decrement, 760d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov R.string.date_picker_decrement_year_button); 761d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov } 762d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov 763d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov private void trySetContentDescription(View root, int viewId, int contDescResId) { 764d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov View target = root.findViewById(viewId); 765d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov if (target != null) { 766d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov target.setContentDescription(mContext.getString(contDescResId)); 767d11e6151fe88314505fa7adca6278de2e772b11cSvetoslav Ganov } 768a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov } 769a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov 7706304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov private void updateInputState() { 7716304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov // Make sure that if the user changes the value and the IME is active 7726304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov // for one of the inputs if this widget, the IME is closed. If the user 7736304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov // changed the value via the IME and there is a next input the IME will 7746304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov // be shown, otherwise the user chose another means of changing the 7756304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov // value and having the IME up makes no sense. 7766304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov InputMethodManager inputMethodManager = InputMethodManager.peekInstance(); 7776304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov if (inputMethodManager != null) { 7786304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov if (inputMethodManager.isActive(mYearSpinnerInput)) { 7796304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mYearSpinnerInput.clearFocus(); 7806304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 7816304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov } else if (inputMethodManager.isActive(mMonthSpinnerInput)) { 7826304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mMonthSpinnerInput.clearFocus(); 7836304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 7846304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov } else if (inputMethodManager.isActive(mDaySpinnerInput)) { 7856304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov mDaySpinnerInput.clearFocus(); 7866304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 7876304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov } 7886304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov } 7896304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov } 7906304b0d58e74509a9f21b67b5227b2fee2f1b60fSvetoslav Ganov 791a53efe9923bedab4fe5d578f32eaff308e5b9e76Svetoslav Ganov /** 79250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Class for managing state storing/restoring. 79350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 79450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private static class SavedState extends BaseSavedState { 79550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 79650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mYear; 79750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 79850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mMonth; 79950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 80050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private final int mDay; 80150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 80250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 80350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link DatePicker#onSaveInstanceState()} 80450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 80550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcelable superState, int year, int month, int day) { 80650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(superState); 80750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = year; 80850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = month; 80950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = day; 81050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 81150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 81250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 81350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Constructor called from {@link #CREATOR} 81450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 81550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov private SavedState(Parcel in) { 81650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super(in); 81750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mYear = in.readInt(); 81850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mMonth = in.readInt(); 81950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov mDay = in.readInt(); 820e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 82150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 82250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @Override 82350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public void writeToParcel(Parcel dest, int flags) { 82450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov super.writeToParcel(dest, flags); 82550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mYear); 82650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mMonth); 82750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov dest.writeInt(mDay); 82850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 82950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 83050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov @SuppressWarnings("all") 83150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov // suppress unused and hiding 83250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { 83350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 83450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState createFromParcel(Parcel in) { 83550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState(in); 83650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 83750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 83850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public SavedState[] newArray(int size) { 83950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return new SavedState[size]; 84050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 84150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov }; 842e3491b6b5f1d3fb871074766597b275d9f682faaKenneth Andersson } 8433fec3fe0e3a83c5e0d1264f34bcc55b158537bc6Svetoslav Ganov} 844