Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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;
 
 
 
This class is a widget for selecting a date. The date can be selected by a 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. Also the minimal and maximal date from which dates to be selected can be customized.

See the Date Picker tutorial.

For a dialog using this view, see android.app.DatePickerDialog.

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
 
 public class DatePicker extends FrameLayout {
 
     private static final String LOG_TAG = DatePicker.class.getSimpleName();
 
     private static final String DATE_FORMAT = "MM/dd/yyyy";
 
     private static final int DEFAULT_START_YEAR = 1900;
 
     private static final int DEFAULT_END_YEAR = 2100;
 
     private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
 
     private static final boolean DEFAULT_SPINNERS_SHOWN = true;
 
     private static final boolean DEFAULT_ENABLED_STATE = true;
 
     private final LinearLayout mSpinners;
 
     private final NumberPicker mDaySpinner;
 
     private final NumberPicker mMonthSpinner;
 
     private final NumberPicker mYearSpinner;
 
     private final EditText mDaySpinnerInput;
 
     private final EditText mMonthSpinnerInput;
 
     private final EditText mYearSpinnerInput;
    private final CalendarView mCalendarView;
    private Locale mCurrentLocale;
    private String[] mShortMonths;
    private final java.text.DateFormat mDateFormat = new SimpleDateFormat();
    private int mNumberOfMonths;
    private Calendar mTempDate;
    private Calendar mMinDate;
    private Calendar mMaxDate;
    private Calendar mCurrentDate;
    private boolean mIsEnabled = ;

    
The callback used to indicate the user changes\d the date.
    public interface OnDateChangedListener {

        
Called upon a date change.

Parameters:
view The view associated with this listener.
year The year that was set.
monthOfYear The month that was set (0-11) for compatibility with java.util.Calendar.
dayOfMonth The day of the month that was set.
        void onDateChanged(DatePicker viewint yearint monthOfYearint dayOfMonth);
    }
    public DatePicker(Context context) {
        this(contextnull);
    }
    public DatePicker(Context contextAttributeSet attrs) {
        this(contextattrs..);
    }
    public DatePicker(Context contextAttributeSet attrsint defStyle) {
        super(contextattrsdefStyle);
        // initialization based on locale
        setCurrentLocale(Locale.getDefault());
        TypedArray attributesArray = context.obtainStyledAttributes(attrs..,
                defStyle, 0);
        boolean spinnersShown = attributesArray.getBoolean(..,
                );
        boolean calendarViewShown = attributesArray.getBoolean(
        int startYear = attributesArray.getInt(..,
                );
        int endYear = attributesArray.getInt(..);
        String minDate = attributesArray.getString(..);
        String maxDate = attributesArray.getString(..);
        int layoutResourceId = attributesArray.getResourceId(..,
                ..);
        attributesArray.recycle();
        LayoutInflater inflater = (LayoutInflatercontext
                .getSystemService(.);
        inflater.inflate(layoutResourceIdthistrue);
        OnValueChangeListener onChangeListener = new OnValueChangeListener() {
            public void onValueChange(NumberPicker pickerint oldValint newVal) {
                updateInputState();
                .setTimeInMillis(.getTimeInMillis());
                // take care of wrapping of days and months to update greater fields
                if (picker == ) {
                    int maxDayOfMonth = .getActualMaximum(.);
                    if (oldVal == maxDayOfMonth && newVal == 1) {
                        .add(., 1);
                    } else if (oldVal == 1 && newVal == maxDayOfMonth) {
                        .add(., -1);
                    } else {
                        .add(.newVal - oldVal);
                    }
                } else if (picker == ) {
                    if (oldVal == 11 && newVal == 0) {
                        .add(., 1);
                    } else if (oldVal == 0 && newVal == 11) {
                        .add(., -1);
                    } else {
                        .add(.newVal - oldVal);
                    }
                } else if (picker == ) {
                    .set(.newVal);
                } else {
                    throw new IllegalArgumentException();
                }
                // now set the date to the adjusted one
                setDate(.get(.), .get(.),
                        .get(.));
                updateSpinners();
                updateCalendarView();
                notifyDateChanged();
            }
        };
        // calendar view day-picker
            public void onSelectedDayChange(CalendarView viewint yearint monthint monthDay) {
                setDate(yearmonthmonthDay);
                updateSpinners();
                notifyDateChanged();
            }
        });
        // day
         = (NumberPickerfindViewById(..);
        .setOnValueChangedListener(onChangeListener);
        // month
        .setMinValue(0);
        .setOnValueChangedListener(onChangeListener);
        // year
        .setOnValueChangedListener(onChangeListener);
        // show only what the user required but make sure we
        // show something and the spinners have higher priority
        if (!spinnersShown && !calendarViewShown) {
            setSpinnersShown(true);
        } else {
            setSpinnersShown(spinnersShown);
            setCalendarViewShown(calendarViewShown);
        }
        // set the min date giving priority of the minDate over startYear
        .clear();
        if (!TextUtils.isEmpty(minDate)) {
            if (!parseDate(minDate)) {
                .set(startYear, 0, 1);
            }
        } else {
            .set(startYear, 0, 1);
        }
        // set the max date giving priority of the maxDate over endYear
        .clear();
        if (!TextUtils.isEmpty(maxDate)) {
            if (!parseDate(maxDate)) {
                .set(endYear, 11, 31);
            }
        } else {
            .set(endYear, 11, 31);
        }
        // initialize to current date
                .get(.), null);
        // re-order the number spinners to match the current date format
        reorderSpinners();
        // accessibility
        setContentDescriptions();
        // If not explicitly specified this view is important for accessibility.
        }
    }

    
Gets the minimal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in java.util.TimeZone.getDefault() time zone.

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

Returns:
The minimal supported date.
    public long getMinDate() {
        return .getMinDate();
    }

    
Sets the minimal date supported by this NumberPicker in milliseconds since January 1, 1970 00:00:00 in java.util.TimeZone.getDefault() time zone.

Parameters:
minDate The minimal supported date.
    public void setMinDate(long minDate) {
        .setTimeInMillis(minDate);
        if (.get(.) == .get(.)
                && .get(.) != .get(.)) {
            return;
        }
        .setTimeInMillis(minDate);
        .setMinDate(minDate);
        if (.before()) {
            updateCalendarView();
        }
        updateSpinners();
    }

    
Gets the maximal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in java.util.TimeZone.getDefault() time zone.

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

Returns:
The maximal supported date.
    public long getMaxDate() {
        return .getMaxDate();
    }

    
Sets the maximal date supported by this DatePicker in milliseconds since January 1, 1970 00:00:00 in java.util.TimeZone.getDefault() time zone.

Parameters:
maxDate The maximal supported date.
    public void setMaxDate(long maxDate) {
        .setTimeInMillis(maxDate);
        if (.get(.) == .get(.)
                && .get(.) != .get(.)) {
            return;
        }
        .setTimeInMillis(maxDate);
        .setMaxDate(maxDate);
        if (.after()) {
            updateCalendarView();
        }
        updateSpinners();
    }
    @Override
    public void setEnabled(boolean enabled) {
        if ( == enabled) {
            return;
        }
        super.setEnabled(enabled);
        .setEnabled(enabled);
        .setEnabled(enabled);
        .setEnabled(enabled);
        .setEnabled(enabled);
         = enabled;
    }
    @Override
    public boolean isEnabled() {
        return ;
    }
    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        onPopulateAccessibilityEvent(event);
        return true;
    }
    @Override
    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(event);
        final int flags = . | .;
        String selectedDateUtterance = DateUtils.formatDateTime(,
                .getTimeInMillis(), flags);
        event.getText().add(selectedDateUtterance);
    }
    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(event);
        event.setClassName(DatePicker.class.getName());
    }
    @Override
        super.onInitializeAccessibilityNodeInfo(info);
        info.setClassName(DatePicker.class.getName());
    }
    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setCurrentLocale(newConfig.locale);
    }

    
Gets whether the CalendarView is shown.

Returns:
True if the calendar view is shown.
See also:
getCalendarView()
    public boolean getCalendarViewShown() {
        return .isShown();
    }

    
Gets the CalendarView.

Returns:
The calendar view.
See also:
getCalendarViewShown()
    public CalendarView getCalendarView () {
        return ;
    }

    
Sets whether the CalendarView is shown.

Parameters:
shown True if the calendar view is to be shown.
    public void setCalendarViewShown(boolean shown) {
        .setVisibility(shown ?  : );
    }

    
Gets whether the spinners are shown.

Returns:
True if the spinners are shown.
    public boolean getSpinnersShown() {
        return .isShown();
    }

    
Sets whether the spinners are shown.

Parameters:
shown True if the spinners are to be shown.
    public void setSpinnersShown(boolean shown) {
        .setVisibility(shown ?  : );
    }

    
Sets the current locale.

Parameters:
locale The current locale.
    private void setCurrentLocale(Locale locale) {
        if (locale.equals()) {
            return;
        }
         = locale;
         = getCalendarForLocale(locale);
         = getCalendarForLocale(locale);
         = getCalendarForLocale(locale);
         = getCalendarForLocale(locale);
         = new String[];
        for (int i = 0; i < i++) {
            [i] = DateUtils.getMonthString(. + i,
                    .);
        }
    }

    
Gets a calendar for locale bootstrapped with the value of a given calendar.

Parameters:
oldCalendar The old calendar.
locale The locale.
    private Calendar getCalendarForLocale(Calendar oldCalendarLocale locale) {
        if (oldCalendar == null) {
            return Calendar.getInstance(locale);
        } else {
            final long currentTimeMillis = oldCalendar.getTimeInMillis();
            Calendar newCalendar = Calendar.getInstance(locale);
            newCalendar.setTimeInMillis(currentTimeMillis);
            return newCalendar;
        }
    }

    
Reorders the spinners according to the date format that is explicitly set by the user and if no such is set fall back to the current locale's default format.
    private void reorderSpinners() {
        .removeAllViews();
        char[] order = DateFormat.getDateFormatOrder(getContext());
        final int spinnerCount = order.length;
        for (int i = 0; i < spinnerCounti++) {
            switch (order[i]) {
                case .:
                    .addView();
                    setImeOptions(spinnerCounti);
                    break;
                case .:
                    .addView();
                    setImeOptions(spinnerCounti);
                    break;
                case .:
                    .addView();
                    setImeOptions(spinnerCounti);
                    break;
                default:
                    throw new IllegalArgumentException();
            }
        }
    }

    
Updates the current date.

Parameters:
year The year.
month The month which is starting from zero.
dayOfMonth The day of the month.
    public void updateDate(int yearint monthint dayOfMonth) {
        if (!isNewDate(yearmonthdayOfMonth)) {
            return;
        }
        setDate(yearmonthdayOfMonth);
        updateSpinners();
        updateCalendarView();
        notifyDateChanged();
    }
    // Override so we are in complete control of save / restore for this widget.
    @Override
    protected void dispatchRestoreInstanceState(SparseArray<Parcelablecontainer) {
        dispatchThawSelfOnly(container);
    }
    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        return new SavedState(superStategetYear(), getMonth(), getDayOfMonth());
    }
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedStatestate;
        super.onRestoreInstanceState(ss.getSuperState());
        setDate(ss.mYearss.mMonthss.mDay);
        updateSpinners();
        updateCalendarView();
    }

    
Initialize the state. If the provided values designate an inconsistent date the values are normalized before updating the spinners.

Parameters:
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.
    public void init(int yearint monthOfYearint dayOfMonth,
            OnDateChangedListener onDateChangedListener) {
        setDate(yearmonthOfYeardayOfMonth);
        updateSpinners();
        updateCalendarView();
         = onDateChangedListener;
    }

    
Parses the given date and in case of success sets the result to the outDate.

Returns:
True if the date was parsed.
    private boolean parseDate(String dateCalendar outDate) {
        try {
            outDate.setTime(.parse(date));
            return true;
        } catch (ParseException e) {
            Log.w("Date: " + date + " not in format: " + );
            return false;
        }
    }
    private boolean isNewDate(int yearint monthint dayOfMonth) {
        return (.get(.) != year
                || .get(.) != dayOfMonth
                || .get(.) != month);
    }
    private void setDate(int yearint monthint dayOfMonth) {
        .set(yearmonthdayOfMonth);
        if (.before()) {
        } else if (.after()) {
        }
    }
    private void updateSpinners() {
        // set the spinner ranges respecting the min and max dates
        if (.equals()) {
            .setWrapSelectorWheel(false);
            .setDisplayedValues(null);
            .setWrapSelectorWheel(false);
        } else if (.equals()) {
            .setWrapSelectorWheel(false);
            .setDisplayedValues(null);
            .setWrapSelectorWheel(false);
        } else {
            .setMinValue(1);
            .setWrapSelectorWheel(true);
            .setDisplayedValues(null);
            .setMinValue(0);
            .setMaxValue(11);
            .setWrapSelectorWheel(true);
        }
        // make sure the month names are a zero based array
        // with the months in the month spinner
        String[] displayedValues = Arrays.copyOfRange(,
                .getMinValue(), .getMaxValue() + 1);
        .setDisplayedValues(displayedValues);
        // year spinner range does not change based on the current date
        .setWrapSelectorWheel(false);
        // set the spinner values
    }

    
Updates the calendar view with the current date.
    private void updateCalendarView() {
         .setDate(.getTimeInMillis(), falsefalse);
    }

    

Returns:
The selected year.
    public int getYear() {
        return .get(.);
    }

    

Returns:
The selected month.
    public int getMonth() {
        return .get(.);
    }

    

Returns:
The selected day of month.
    public int getDayOfMonth() {
        return .get(.);
    }

    
Notifies the listener, if such, for a change in the selected date.
    private void notifyDateChanged() {
        if ( != null) {
            .onDateChanged(thisgetYear(), getMonth(), getDayOfMonth());
        }
    }

    
Sets the IME options for a spinner based on its ordering.

Parameters:
spinner The spinner.
spinnerCount The total spinner count.
spinnerIndex The index of the given spinner.
    private void setImeOptions(NumberPicker spinnerint spinnerCountint spinnerIndex) {
        final int imeOptions;
        if (spinnerIndex < spinnerCount - 1) {
            imeOptions = .;
        } else {
            imeOptions = .;
        }
        TextView input = (TextViewspinner.findViewById(..);
        input.setImeOptions(imeOptions);
    }
    private void setContentDescriptions() {
        // Day
                ..);
                ..);
        // Month
                ..);
                ..);
        // Year
                ..);
                ..);
    }
    private void trySetContentDescription(View rootint viewIdint contDescResId) {
        View target = root.findViewById(viewId);
        if (target != null) {
            target.setContentDescription(.getString(contDescResId));
        }
    }
    private void updateInputState() {
        // Make sure that if the user changes the value and the IME is active
        // for one of the inputs if this widget, the IME is closed. If the user
        // changed the value via the IME and there is a next input the IME will
        // be shown, otherwise the user chose another means of changing the
        // value and having the IME up makes no sense.
        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
        if (inputMethodManager != null) {
            if (inputMethodManager.isActive()) {
                .clearFocus();
                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
            } else if (inputMethodManager.isActive()) {
                .clearFocus();
                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
            } else if (inputMethodManager.isActive()) {
                .clearFocus();
                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
            }
        }
    }

    
Class for managing state storing/restoring.
    private static class SavedState extends BaseSavedState {
        private final int mYear;
        private final int mMonth;
        private final int mDay;

        
Constructor called from DatePicker.onSaveInstanceState()
        private SavedState(Parcelable superStateint yearint monthint day) {
            super(superState);
             = year;
             = month;
             = day;
        }

        
Constructor called from CREATOR
        private SavedState(Parcel in) {
            super(in);
             = in.readInt();
             = in.readInt();
             = in.readInt();
        }
        @Override
        public void writeToParcel(Parcel destint flags) {
            super.writeToParcel(destflags);
            dest.writeInt();
            dest.writeInt();
            dest.writeInt();
        }
        @SuppressWarnings("all")
        // suppress unused and hiding
        public static final Parcelable.Creator<SavedStateCREATOR = new Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }