/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.widget;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.icu.util.Calendar;
import android.icu.util.TimeZone;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewStructure;
import android.view.accessibility.AccessibilityEvent;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;

import com.android.internal.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Locale;

Provides a widget for selecting a date.

When the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to spinner, the date can be selected using year, month, and day spinners or a CalendarView. The set of spinners and the calendar view are automatically synchronized. The client can customize whether only the spinners, or only the calendar view, or both to be displayed.

When the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar, the month and day can be selected using a calendar-style view while the year can be selected separately using a list.

See the Pickers guide.

For a dialog using this view, see DatePickerDialog.

@attrref android.R.styleable#DatePicker_startYear
@attrref android.R.styleable#DatePicker_endYear
@attrref android.R.styleable#DatePicker_maxDate
@attrref android.R.styleable#DatePicker_minDate
@attrref android.R.styleable#DatePicker_spinnersShown
@attrref android.R.styleable#DatePicker_calendarViewShown
@attrref android.R.styleable#DatePicker_dayOfWeekBackground
@attrref android.R.styleable#DatePicker_dayOfWeekTextAppearance
@attrref android.R.styleable#DatePicker_headerBackground
@attrref android.R.styleable#DatePicker_headerMonthTextAppearance
@attrref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance
@attrref android.R.styleable#DatePicker_headerYearTextAppearance
@attrref android.R.styleable#DatePicker_yearListItemTextAppearance
@attrref android.R.styleable#DatePicker_yearListSelectorColor
@attrref android.R.styleable#DatePicker_calendarTextColor
@attrref android.R.styleable#DatePicker_datePickerMode
/** * Provides a widget for selecting a date. * <p> * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is * set to {@code spinner}, the date can be selected using year, month, and day * spinners or a {@link CalendarView}. The set of spinners and the calendar * view are automatically synchronized. The client can customize whether only * the spinners, or only the calendar view, or both to be displayed. * </p> * <p> * When the {@link android.R.styleable#DatePicker_datePickerMode} attribute is * set to {@code calendar}, the month and day can be selected using a * calendar-style view while the year can be selected separately using a list. * </p> * <p> * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> * guide. * </p> * <p> * For a dialog using this view, see {@link android.app.DatePickerDialog}. * </p> * * @attr ref android.R.styleable#DatePicker_startYear * @attr ref android.R.styleable#DatePicker_endYear * @attr ref android.R.styleable#DatePicker_maxDate * @attr ref android.R.styleable#DatePicker_minDate * @attr ref android.R.styleable#DatePicker_spinnersShown * @attr ref android.R.styleable#DatePicker_calendarViewShown * @attr ref android.R.styleable#DatePicker_dayOfWeekBackground * @attr ref android.R.styleable#DatePicker_dayOfWeekTextAppearance * @attr ref android.R.styleable#DatePicker_headerBackground * @attr ref android.R.styleable#DatePicker_headerMonthTextAppearance * @attr ref android.R.styleable#DatePicker_headerDayOfMonthTextAppearance * @attr ref android.R.styleable#DatePicker_headerYearTextAppearance * @attr ref android.R.styleable#DatePicker_yearListItemTextAppearance * @attr ref android.R.styleable#DatePicker_yearListSelectorColor * @attr ref android.R.styleable#DatePicker_calendarTextColor * @attr ref android.R.styleable#DatePicker_datePickerMode */
@Widget public class DatePicker extends FrameLayout { private static final String LOG_TAG = DatePicker.class.getSimpleName();
Presentation mode for the Holo-style date picker that uses a set of NumberPickers.
See Also:
@hideVisible for testing only.
/** * Presentation mode for the Holo-style date picker that uses a set of * {@link android.widget.NumberPicker}s. * * @see #getMode() * @hide Visible for testing only. */
@TestApi public static final int MODE_SPINNER = 1;
Presentation mode for the Material-style date picker that uses a calendar.
See Also:
  • getMode()
@hideVisible for testing only.
/** * Presentation mode for the Material-style date picker that uses a * calendar. * * @see #getMode() * @hide Visible for testing only. */
@TestApi public static final int MODE_CALENDAR = 2;
@hide
/** @hide */
@IntDef(prefix = { "MODE_" }, value = { MODE_SPINNER, MODE_CALENDAR }) @Retention(RetentionPolicy.SOURCE) public @interface DatePickerMode {} private final DatePickerDelegate mDelegate; @DatePickerMode private final int mMode;
The callback used to indicate the user changed the date.
/** * The callback used to indicate the user changed the date. */
public interface OnDateChangedListener {
Called upon a date change.
Params:
  • view – The view associated with this listener.
  • year – The year that was set.
  • monthOfYear – The month that was set (0-11) for compatibility with Calendar.
  • dayOfMonth – The day of the month that was set.
/** * Called upon a date change. * * @param view The view associated with this listener. * @param year The year that was set. * @param monthOfYear The month that was set (0-11) for compatibility * with {@link java.util.Calendar}. * @param dayOfMonth The day of the month that was set. */
void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth); } public DatePicker(Context context) { this(context, null); } public DatePicker(Context context, AttributeSet attrs) { this(context, attrs, R.attr.datePickerStyle); } public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); // DatePicker is important by default, unless app developer overrode attribute. if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) { setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES); } final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker, defStyleAttr, defStyleRes); final boolean isDialogMode = a.getBoolean(R.styleable.DatePicker_dialogMode, false); final int requestedMode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER); final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0); a.recycle(); if (requestedMode == MODE_CALENDAR && isDialogMode) { // You want MODE_CALENDAR? YOU CAN'T HANDLE MODE_CALENDAR! Well, // maybe you can depending on your screen size. Let's check... mMode = context.getResources().getInteger(R.integer.date_picker_mode); } else { mMode = requestedMode; } switch (mMode) { case MODE_CALENDAR: mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes); break; case MODE_SPINNER: default: mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes); break; } if (firstDayOfWeek != 0) { setFirstDayOfWeek(firstDayOfWeek); } mDelegate.setAutoFillChangeListener((v, y, m, d) -> { final AutofillManager afm = context.getSystemService(AutofillManager.class); if (afm != null) { afm.notifyValueChanged(this); } }); } private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { return new DatePickerSpinnerDelegate(this, context, attrs, defStyleAttr, defStyleRes); } private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr, defStyleRes); }
Returns:the picker's presentation mode, one of MODE_CALENDAR or MODE_SPINNER
@attrref android.R.styleable#DatePicker_datePickerMode
@hideVisible for testing only.
/** * @return the picker's presentation mode, one of {@link #MODE_CALENDAR} or * {@link #MODE_SPINNER} * @attr ref android.R.styleable#DatePicker_datePickerMode * @hide Visible for testing only. */
@DatePickerMode @TestApi public int getMode() { return mMode; }
Initialize the state. If the provided values designate an inconsistent date the values are normalized before updating the spinners.
Params:
  • year – The initial year.
  • monthOfYear – The initial month starting from zero.
  • dayOfMonth – The initial day of the month.
  • onDateChangedListener – How user is notified date is changed by user, can be null.
/** * Initialize the state. If the provided values designate an inconsistent * date the values are normalized before updating the spinners. * * @param year The initial year. * @param monthOfYear The initial month <strong>starting from zero</strong>. * @param dayOfMonth The initial day of the month. * @param onDateChangedListener How user is notified date is changed by * user, can be null. */
public void init(int year, int monthOfYear, int dayOfMonth, OnDateChangedListener onDateChangedListener) { mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener); }
Set the callback that indicates the date has been adjusted by the user.
Params:
  • onDateChangedListener – How user is notified date is changed by user, can be null.
/** * Set the callback that indicates the date has been adjusted by the user. * * @param onDateChangedListener How user is notified date is changed by * user, can be null. */
public void setOnDateChangedListener(OnDateChangedListener onDateChangedListener) { mDelegate.setOnDateChangedListener(onDateChangedListener); }
Update the current date.
Params:
  • year – The year.
  • month – The month which is starting from zero.
  • dayOfMonth – The day of the month.
/** * Update the current date. * * @param year The year. * @param month The month which is <strong>starting from zero</strong>. * @param dayOfMonth The day of the month. */
public void updateDate(int year, int month, int dayOfMonth) { mDelegate.updateDate(year, month, dayOfMonth); }
Returns:The selected year.
/** * @return The selected year. */
public int getYear() { return mDelegate.getYear(); }
Returns:The selected month.
/** * @return The selected month. */
public int getMonth() { return mDelegate.getMonth(); }
Returns:The selected day of month.
/** * @return The selected day of month. */
public int getDayOfMonth() { return mDelegate.getDayOfMonth(); }
Gets the minimal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in getDefault.getDefault() time zone.

Note: The default minimal date is 01/01/1900.

Returns:The minimal supported date.
/** * Gets the minimal date supported by this {@link DatePicker} in * milliseconds since January 1, 1970 00:00:00 in * {@link TimeZone#getDefault()} time zone. * <p> * Note: The default minimal date is 01/01/1900. * <p> * * @return The minimal supported date. */
public long getMinDate() { return mDelegate.getMinDate().getTimeInMillis(); }
Sets the minimal date supported by this NumberPicker in milliseconds since January 1, 1970 00:00:00 in getDefault.getDefault() time zone.
Params:
  • minDate – The minimal supported date.
/** * Sets the minimal date supported by this {@link NumberPicker} in * milliseconds since January 1, 1970 00:00:00 in * {@link TimeZone#getDefault()} time zone. * * @param minDate The minimal supported date. */
public void setMinDate(long minDate) { mDelegate.setMinDate(minDate); }
Gets the maximal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in getDefault.getDefault() time zone.

Note: The default maximal date is 12/31/2100.

Returns:The maximal supported date.
/** * Gets the maximal date supported by this {@link DatePicker} in * milliseconds since January 1, 1970 00:00:00 in * {@link TimeZone#getDefault()} time zone. * <p> * Note: The default maximal date is 12/31/2100. * <p> * * @return The maximal supported date. */
public long getMaxDate() { return mDelegate.getMaxDate().getTimeInMillis(); }
Sets the maximal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in getDefault.getDefault() time zone.
Params:
  • maxDate – The maximal supported date.
/** * Sets the maximal date supported by this {@link DatePicker} in * milliseconds since January 1, 1970 00:00:00 in * {@link TimeZone#getDefault()} time zone. * * @param maxDate The maximal supported date. */
public void setMaxDate(long maxDate) { mDelegate.setMaxDate(maxDate); }
Sets the callback that indicates the current date is valid.
Params:
  • callback – the callback, may be null
@hide
/** * Sets the callback that indicates the current date is valid. * * @param callback the callback, may be null * @hide */
public void setValidationCallback(@Nullable ValidationCallback callback) { mDelegate.setValidationCallback(callback); } @Override public void setEnabled(boolean enabled) { if (mDelegate.isEnabled() == enabled) { return; } super.setEnabled(enabled); mDelegate.setEnabled(enabled); } @Override public boolean isEnabled() { return mDelegate.isEnabled(); }
@hide
/** @hide */
@Override public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) { return mDelegate.dispatchPopulateAccessibilityEvent(event); }
@hide
/** @hide */
@Override public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) { super.onPopulateAccessibilityEventInternal(event); mDelegate.onPopulateAccessibilityEvent(event); } @Override public CharSequence getAccessibilityClassName() { return DatePicker.class.getName(); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDelegate.onConfigurationChanged(newConfig); }
Sets the first day of week.
Params:
  • firstDayOfWeek – The first day of the week conforming to the CalendarView APIs.
See Also:
  • SUNDAY.SUNDAY
  • MONDAY.MONDAY
  • TUESDAY.TUESDAY
  • WEDNESDAY.WEDNESDAY
  • THURSDAY.THURSDAY
  • FRIDAY.FRIDAY
  • SATURDAY.SATURDAY
@attrref android.R.styleable#DatePicker_firstDayOfWeek
/** * Sets the first day of week. * * @param firstDayOfWeek The first day of the week conforming to the * {@link CalendarView} APIs. * @see Calendar#SUNDAY * @see Calendar#MONDAY * @see Calendar#TUESDAY * @see Calendar#WEDNESDAY * @see Calendar#THURSDAY * @see Calendar#FRIDAY * @see Calendar#SATURDAY * * @attr ref android.R.styleable#DatePicker_firstDayOfWeek */
public void setFirstDayOfWeek(int firstDayOfWeek) { if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7"); } mDelegate.setFirstDayOfWeek(firstDayOfWeek); }
Gets the first day of week.
See Also:
  • SUNDAY.SUNDAY
  • MONDAY.MONDAY
  • TUESDAY.TUESDAY
  • WEDNESDAY.WEDNESDAY
  • THURSDAY.THURSDAY
  • FRIDAY.FRIDAY
  • SATURDAY.SATURDAY
Returns:The first day of the week conforming to the CalendarView APIs.
@attrref android.R.styleable#DatePicker_firstDayOfWeek
/** * Gets the first day of week. * * @return The first day of the week conforming to the {@link CalendarView} * APIs. * @see Calendar#SUNDAY * @see Calendar#MONDAY * @see Calendar#TUESDAY * @see Calendar#WEDNESDAY * @see Calendar#THURSDAY * @see Calendar#FRIDAY * @see Calendar#SATURDAY * * @attr ref android.R.styleable#DatePicker_firstDayOfWeek */
public int getFirstDayOfWeek() { return mDelegate.getFirstDayOfWeek(); }
Returns whether the CalendarView is shown.

Note: This method returns false when the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar.

See Also:
Returns:true if the calendar view is shown
Deprecated:Not supported by Material-style calendar mode
/** * Returns whether the {@link CalendarView} is shown. * <p> * <strong>Note:</strong> This method returns {@code false} when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @return {@code true} if the calendar view is shown * @see #getCalendarView() * @deprecated Not supported by Material-style {@code calendar} mode */
@Deprecated public boolean getCalendarViewShown() { return mDelegate.getCalendarViewShown(); }
Returns the CalendarView used by this picker.

Note: This method throws an UnsupportedOperationException when the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar.

Throws:
See Also:
Returns:the calendar view
Deprecated:Not supported by Material-style calendar mode
/** * Returns the {@link CalendarView} used by this picker. * <p> * <strong>Note:</strong> This method throws an * {@link UnsupportedOperationException} when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @return the calendar view * @see #getCalendarViewShown() * @deprecated Not supported by Material-style {@code calendar} mode * @throws UnsupportedOperationException if called when the picker is * displayed in {@code calendar} mode */
@Deprecated public CalendarView getCalendarView() { return mDelegate.getCalendarView(); }
Sets whether the CalendarView is shown.

Note: Calling this method has no effect when the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar.

Params:
  • shown – true to show the calendar view, false to hide it
Deprecated:Not supported by Material-style calendar mode
/** * Sets whether the {@link CalendarView} is shown. * <p> * <strong>Note:</strong> Calling this method has no effect when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @param shown {@code true} to show the calendar view, {@code false} to * hide it * @deprecated Not supported by Material-style {@code calendar} mode */
@Deprecated public void setCalendarViewShown(boolean shown) { mDelegate.setCalendarViewShown(shown); }
Returns whether the spinners are shown.

Note: his method returns false when the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar.

Returns:true if the spinners are shown
Deprecated:Not supported by Material-style calendar mode
/** * Returns whether the spinners are shown. * <p> * <strong>Note:</strong> his method returns {@code false} when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @return {@code true} if the spinners are shown * @deprecated Not supported by Material-style {@code calendar} mode */
@Deprecated public boolean getSpinnersShown() { return mDelegate.getSpinnersShown(); }
Sets whether the spinners are shown.

Calling this method has no effect when the DatePicker_datePickerMode.DatePicker_datePickerMode attribute is set to calendar.

Params:
  • shown – true to show the spinners, false to hide them
Deprecated:Not supported by Material-style calendar mode
/** * Sets whether the spinners are shown. * <p> * Calling this method has no effect when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @param shown {@code true} to show the spinners, {@code false} to hide * them * @deprecated Not supported by Material-style {@code calendar} mode */
@Deprecated public void setSpinnersShown(boolean shown) { mDelegate.setSpinnersShown(shown); } @Override protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { dispatchThawSelfOnly(container); } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); return mDelegate.onSaveInstanceState(superState); } @Override protected void onRestoreInstanceState(Parcelable state) { BaseSavedState ss = (BaseSavedState) state; super.onRestoreInstanceState(ss.getSuperState()); mDelegate.onRestoreInstanceState(ss); }
A delegate interface that defined the public API of the DatePicker. Allows different DatePicker implementations. This would need to be implemented by the DatePicker delegates for the real behavior.
@hide
/** * A delegate interface that defined the public API of the DatePicker. Allows different * DatePicker implementations. This would need to be implemented by the DatePicker delegates * for the real behavior. * * @hide */
interface DatePickerDelegate { void init(int year, int monthOfYear, int dayOfMonth, OnDateChangedListener onDateChangedListener); void setOnDateChangedListener(OnDateChangedListener onDateChangedListener); void setAutoFillChangeListener(OnDateChangedListener onDateChangedListener); void updateDate(int year, int month, int dayOfMonth); int getYear(); int getMonth(); int getDayOfMonth(); void autofill(AutofillValue value); AutofillValue getAutofillValue(); void setFirstDayOfWeek(int firstDayOfWeek); int getFirstDayOfWeek(); void setMinDate(long minDate); Calendar getMinDate(); void setMaxDate(long maxDate); Calendar getMaxDate(); void setEnabled(boolean enabled); boolean isEnabled(); CalendarView getCalendarView(); void setCalendarViewShown(boolean shown); boolean getCalendarViewShown(); void setSpinnersShown(boolean shown); boolean getSpinnersShown(); void setValidationCallback(ValidationCallback callback); void onConfigurationChanged(Configuration newConfig); Parcelable onSaveInstanceState(Parcelable superState); void onRestoreInstanceState(Parcelable state); boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event); void onPopulateAccessibilityEvent(AccessibilityEvent event); }
An abstract class which can be used as a start for DatePicker implementations
/** * An abstract class which can be used as a start for DatePicker implementations */
abstract static class AbstractDatePickerDelegate implements DatePickerDelegate { // The delegator protected DatePicker mDelegator; // The context protected Context mContext; // NOTE: when subclasses change this variable, they must call resetAutofilledValue(). protected Calendar mCurrentDate; // The current locale protected Locale mCurrentLocale; // Callbacks protected OnDateChangedListener mOnDateChangedListener; protected OnDateChangedListener mAutoFillChangeListener; protected ValidationCallback mValidationCallback; // The value that was passed to autofill() - it must be stored because it getAutofillValue() // must return the exact same value that was autofilled, otherwise the widget will not be // properly highlighted after autofill(). private long mAutofilledValue; public AbstractDatePickerDelegate(DatePicker delegator, Context context) { mDelegator = delegator; mContext = context; setCurrentLocale(Locale.getDefault()); } protected void setCurrentLocale(Locale locale) { if (!locale.equals(mCurrentLocale)) { mCurrentLocale = locale; onLocaleChanged(locale); } } @Override public void setOnDateChangedListener(OnDateChangedListener callback) { mOnDateChangedListener = callback; } @Override public void setAutoFillChangeListener(OnDateChangedListener callback) { mAutoFillChangeListener = callback; } @Override public void setValidationCallback(ValidationCallback callback) { mValidationCallback = callback; } @Override public final void autofill(AutofillValue value) { if (value == null || !value.isDate()) { Log.w(LOG_TAG, value + " could not be autofilled into " + this); return; } final long time = value.getDateValue(); final Calendar cal = Calendar.getInstance(mCurrentLocale); cal.setTimeInMillis(time); updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); // Must set mAutofilledValue *after* calling subclass method to make sure the value // returned by getAutofillValue() matches it. mAutofilledValue = time; } @Override public final AutofillValue getAutofillValue() { final long time = mAutofilledValue != 0 ? mAutofilledValue : mCurrentDate.getTimeInMillis(); return AutofillValue.forDate(time); }
This method must be called every time the value of the year, month, and/or day is changed by a subclass method.
/** * This method must be called every time the value of the year, month, and/or day is * changed by a subclass method. */
protected void resetAutofilledValue() { mAutofilledValue = 0; } protected void onValidationChanged(boolean valid) { if (mValidationCallback != null) { mValidationCallback.onValidationChanged(valid); } } protected void onLocaleChanged(Locale locale) { // Stub. } @Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { event.getText().add(getFormattedCurrentDate()); } protected String getFormattedCurrentDate() { return DateUtils.formatDateTime(mContext, mCurrentDate.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY); }
Class for managing state storing/restoring.
/** * Class for managing state storing/restoring. */
static class SavedState extends View.BaseSavedState { private final int mSelectedYear; private final int mSelectedMonth; private final int mSelectedDay; private final long mMinDate; private final long mMaxDate; private final int mCurrentView; private final int mListPosition; private final int mListPositionOffset; public SavedState(Parcelable superState, int year, int month, int day, long minDate, long maxDate) { this(superState, year, month, day, minDate, maxDate, 0, 0, 0); }
Constructor called from DatePicker.onSaveInstanceState()
/** * Constructor called from {@link DatePicker#onSaveInstanceState()} */
public SavedState(Parcelable superState, int year, int month, int day, long minDate, long maxDate, int currentView, int listPosition, int listPositionOffset) { super(superState); mSelectedYear = year; mSelectedMonth = month; mSelectedDay = day; mMinDate = minDate; mMaxDate = maxDate; mCurrentView = currentView; mListPosition = listPosition; mListPositionOffset = listPositionOffset; }
Constructor called from CREATOR
/** * Constructor called from {@link #CREATOR} */
private SavedState(Parcel in) { super(in); mSelectedYear = in.readInt(); mSelectedMonth = in.readInt(); mSelectedDay = in.readInt(); mMinDate = in.readLong(); mMaxDate = in.readLong(); mCurrentView = in.readInt(); mListPosition = in.readInt(); mListPositionOffset = in.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mSelectedYear); dest.writeInt(mSelectedMonth); dest.writeInt(mSelectedDay); dest.writeLong(mMinDate); dest.writeLong(mMaxDate); dest.writeInt(mCurrentView); dest.writeInt(mListPosition); dest.writeInt(mListPositionOffset); } public int getSelectedDay() { return mSelectedDay; } public int getSelectedMonth() { return mSelectedMonth; } public int getSelectedYear() { return mSelectedYear; } public long getMinDate() { return mMinDate; } public long getMaxDate() { return mMaxDate; } public int getCurrentView() { return mCurrentView; } public int getListPosition() { return mListPosition; } public int getListPositionOffset() { return mListPositionOffset; } @SuppressWarnings("all") // suppress unused and hiding public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } }
A callback interface for updating input validity when the date picker when included into a dialog.
@hide
/** * A callback interface for updating input validity when the date picker * when included into a dialog. * * @hide */
public interface ValidationCallback { void onValidationChanged(boolean valid); } @Override public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) { // This view is self-sufficient for autofill, so it needs to call // onProvideAutoFillStructure() to fill itself, but it does not need to call // dispatchProvideAutoFillStructure() to fill its children. structure.setAutofillId(getAutofillId()); onProvideAutofillStructure(structure, flags); } @Override public void autofill(AutofillValue value) { if (!isEnabled()) return; mDelegate.autofill(value); } @Override public @AutofillType int getAutofillType() { return isEnabled() ? AUTOFILL_TYPE_DATE : AUTOFILL_TYPE_NONE; } @Override public AutofillValue getAutofillValue() { return isEnabled() ? mDelegate.getAutofillValue() : null; } }