16b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette/*
26b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * Copyright (C) 2016 The Android Open Source Project
36b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette *
46b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License");
56b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * you may not use this file except in compliance with the License.
66b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * You may obtain a copy of the License at
76b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette *
86b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette *      http://www.apache.org/licenses/LICENSE-2.0
96b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette *
106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * Unless required by applicable law or agreed to in writing, software
116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS,
126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * See the License for the specific language governing permissions and
146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * limitations under the License.
156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette */
166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverettepackage android.widget;
186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.content.Context;
206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.content.res.Configuration;
216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.content.res.TypedArray;
2268763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar;
236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.os.Parcelable;
246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.text.InputType;
256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.text.TextUtils;
266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.text.format.DateFormat;
276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.util.AttributeSet;
286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.LayoutInflater;
296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.View;
306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.accessibility.AccessibilityEvent;
316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.inputmethod.EditorInfo;
326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.view.inputmethod.InputMethodManager;
336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.widget.DatePicker.AbstractDatePickerDelegate;
346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport android.widget.NumberPicker.OnValueChangeListener;
356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3699441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport libcore.icu.ICU;
3799441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas
386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport java.text.DateFormatSymbols;
396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport java.text.ParseException;
406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport java.text.SimpleDateFormat;
416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport java.util.Arrays;
426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteimport java.util.Locale;
436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette/**
456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette * A delegate implementing the basic DatePicker
466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette */
476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viveretteclass DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final String DATE_FORMAT = "MM/dd/yyyy";
506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final int DEFAULT_START_YEAR = 1900;
526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final int DEFAULT_END_YEAR = 2100;
546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final boolean DEFAULT_SPINNERS_SHOWN = true;
586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private static final boolean DEFAULT_ENABLED_STATE = true;
606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final LinearLayout mSpinners;
626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final NumberPicker mDaySpinner;
646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final NumberPicker mMonthSpinner;
666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final NumberPicker mYearSpinner;
686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final EditText mDaySpinnerInput;
706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final EditText mMonthSpinnerInput;
726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final EditText mYearSpinnerInput;
746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final CalendarView mCalendarView;
766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private String[] mShortMonths;
786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private int mNumberOfMonths;
826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private Calendar mTempDate;
846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private Calendar mMinDate;
866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private Calendar mMaxDate;
886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    DatePickerSpinnerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            int defStyleAttr, int defStyleRes) {
936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        super(delegator, context);
946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDelegator = delegator;
966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mContext = context;
976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // initialization based on locale
996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setCurrentLocale(Locale.getDefault());
1006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
1026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.styleable.DatePicker, defStyleAttr, defStyleRes);
1036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        boolean spinnersShown = attributesArray.getBoolean(com.android.internal.R.styleable.DatePicker_spinnersShown,
1046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                DEFAULT_SPINNERS_SHOWN);
1056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        boolean calendarViewShown = attributesArray.getBoolean(
1066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
1076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        int startYear = attributesArray.getInt(com.android.internal.R.styleable.DatePicker_startYear,
1086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                DEFAULT_START_YEAR);
1096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        int endYear = attributesArray.getInt(com.android.internal.R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
1106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        String minDate = attributesArray.getString(com.android.internal.R.styleable.DatePicker_minDate);
1116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        String maxDate = attributesArray.getString(com.android.internal.R.styleable.DatePicker_maxDate);
1126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        int layoutResourceId = attributesArray.getResourceId(
1136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.styleable.DatePicker_legacyLayout, com.android.internal.R.layout.date_picker_legacy);
1146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        attributesArray.recycle();
1156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        LayoutInflater inflater = (LayoutInflater) context
1176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
11843da25c6707b7ddd118bf507865d21cebc4ae70bAdam Powell        final View view = inflater.inflate(layoutResourceId, mDelegator, true);
11943da25c6707b7ddd118bf507865d21cebc4ae70bAdam Powell        view.setSaveFromParentEnabled(false);
1206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        OnValueChangeListener onChangeListener = new OnValueChangeListener() {
1226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
1236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                updateInputState();
1246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
1256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                // take care of wrapping of days and months to update greater fields
1266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                if (picker == mDaySpinner) {
1276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
1286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    if (oldVal == maxDayOfMonth && newVal == 1) {
1296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.DAY_OF_MONTH, 1);
1306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    } else if (oldVal == 1 && newVal == maxDayOfMonth) {
1316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.DAY_OF_MONTH, -1);
1326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    } else {
1336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
1346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    }
1356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                } else if (picker == mMonthSpinner) {
1366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    if (oldVal == 11 && newVal == 0) {
1376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.MONTH, 1);
1386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    } else if (oldVal == 0 && newVal == 11) {
1396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.MONTH, -1);
1406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    } else {
1416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.add(Calendar.MONTH, newVal - oldVal);
1426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    }
1436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                } else if (picker == mYearSpinner) {
1446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    mTempDate.set(Calendar.YEAR, newVal);
1456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                } else {
1466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    throw new IllegalArgumentException();
1476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                }
1486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                // now set the date to the adjusted one
1496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
1506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                        mTempDate.get(Calendar.DAY_OF_MONTH));
1516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                updateSpinners();
1526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                updateCalendarView();
1536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                notifyDateChanged();
1546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
1556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        };
1566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mSpinners = (LinearLayout) mDelegator.findViewById(com.android.internal.R.id.pickers);
1586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // calendar view day-picker
1606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView = (CalendarView) mDelegator.findViewById(com.android.internal.R.id.calendar_view);
1616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
1626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
1636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                setDate(year, month, monthDay);
1646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                updateSpinners();
1656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                notifyDateChanged();
1666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
1676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        });
1686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // day
1706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner = (NumberPicker) mDelegator.findViewById(com.android.internal.R.id.day);
1716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
1726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner.setOnLongPressUpdateInterval(100);
1736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner.setOnValueChangedListener(onChangeListener);
1746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinnerInput = (EditText) mDaySpinner.findViewById(com.android.internal.R.id.numberpicker_input);
1756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // month
1776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner = (NumberPicker) mDelegator.findViewById(com.android.internal.R.id.month);
1786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setMinValue(0);
1796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
1806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setDisplayedValues(mShortMonths);
1816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setOnLongPressUpdateInterval(200);
1826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setOnValueChangedListener(onChangeListener);
1836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(com.android.internal.R.id.numberpicker_input);
1846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // year
1866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner = (NumberPicker) mDelegator.findViewById(com.android.internal.R.id.year);
1876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setOnLongPressUpdateInterval(100);
1886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setOnValueChangedListener(onChangeListener);
1896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinnerInput = (EditText) mYearSpinner.findViewById(com.android.internal.R.id.numberpicker_input);
1906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
1916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // show only what the user required but make sure we
1926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // show something and the spinners have higher priority
1936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (!spinnersShown && !calendarViewShown) {
1946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            setSpinnersShown(true);
1956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
1966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            setSpinnersShown(spinnersShown);
1976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            setCalendarViewShown(calendarViewShown);
1986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
1996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // set the min date giving priority of the minDate over startYear
2016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mTempDate.clear();
2026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (!TextUtils.isEmpty(minDate)) {
2036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            if (!parseDate(minDate, mTempDate)) {
2046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mTempDate.set(startYear, 0, 1);
2056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
2066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
2076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mTempDate.set(startYear, 0, 1);
2086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setMinDate(mTempDate.getTimeInMillis());
2106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // set the max date giving priority of the maxDate over endYear
2126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mTempDate.clear();
2136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (!TextUtils.isEmpty(maxDate)) {
2146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            if (!parseDate(maxDate, mTempDate)) {
2156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mTempDate.set(endYear, 11, 31);
2166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
2176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
2186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mTempDate.set(endYear, 11, 31);
2196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setMaxDate(mTempDate.getTimeInMillis());
2216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // initialize to current date
2236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCurrentDate.setTimeInMillis(System.currentTimeMillis());
2246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
2256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                .get(Calendar.DAY_OF_MONTH), null);
2266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // re-order the number spinners to match the current date format
2286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        reorderSpinners();
2296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // accessibility
2316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setContentDescriptions();
2326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // If not explicitly specified this view is important for accessibility.
2346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mDelegator.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
2356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDelegator.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
2366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void init(int year, int monthOfYear, int dayOfMonth,
2416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                     DatePicker.OnDateChangedListener onDateChangedListener) {
2426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setDate(year, monthOfYear, dayOfMonth);
2436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateSpinners();
2446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateCalendarView();
245a9a75f506efe7e63078bed661f49992e501846f0Alan Viverette
2466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mOnDateChangedListener = onDateChangedListener;
2476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void updateDate(int year, int month, int dayOfMonth) {
2516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (!isNewDate(year, month, dayOfMonth)) {
2526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return;
2536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setDate(year, month, dayOfMonth);
2556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateSpinners();
2566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateCalendarView();
2576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        notifyDateChanged();
2586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public int getYear() {
2626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mCurrentDate.get(Calendar.YEAR);
2636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public int getMonth() {
2676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mCurrentDate.get(Calendar.MONTH);
2686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public int getDayOfMonth() {
2726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
2736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setFirstDayOfWeek(int firstDayOfWeek) {
2776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setFirstDayOfWeek(firstDayOfWeek);
2786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public int getFirstDayOfWeek() {
2826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mCalendarView.getFirstDayOfWeek();
2836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
2846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
2856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
2866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setMinDate(long minDate) {
2876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mTempDate.setTimeInMillis(minDate);
2886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
2893fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) {
2903fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette            // Same day, no-op.
2916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return;
2926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMinDate.setTimeInMillis(minDate);
2946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setMinDate(minDate);
2956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mCurrentDate.before(mMinDate)) {
2966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
2976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            updateCalendarView();
2986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
2996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateSpinners();
3006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public Calendar getMinDate() {
3046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        final Calendar minDate = Calendar.getInstance();
3056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        minDate.setTimeInMillis(mCalendarView.getMinDate());
3066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return minDate;
3076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setMaxDate(long maxDate) {
3116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mTempDate.setTimeInMillis(maxDate);
3126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
3133fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) {
3143fb5c7b8fac6fd5583da10793d0bfa40bc851ed5Alan Viverette            // Same day, no-op.
3156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return;
3166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
3176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMaxDate.setTimeInMillis(maxDate);
3186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setMaxDate(maxDate);
3196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mCurrentDate.after(mMaxDate)) {
3206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
3216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            updateCalendarView();
3226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
3236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        updateSpinners();
3246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public Calendar getMaxDate() {
3286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        final Calendar maxDate = Calendar.getInstance();
3296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        maxDate.setTimeInMillis(mCalendarView.getMaxDate());
3306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return maxDate;
3316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setEnabled(boolean enabled) {
3356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner.setEnabled(enabled);
3366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setEnabled(enabled);
3376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setEnabled(enabled);
3386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setEnabled(enabled);
3396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mIsEnabled = enabled;
3406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public boolean isEnabled() {
3446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mIsEnabled;
3456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public CalendarView getCalendarView() {
3496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mCalendarView;
3506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setCalendarViewShown(boolean shown) {
3546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setVisibility(shown ? View.VISIBLE : View.GONE);
3556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public boolean getCalendarViewShown() {
3596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return (mCalendarView.getVisibility() == View.VISIBLE);
3606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void setSpinnersShown(boolean shown) {
3646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mSpinners.setVisibility(shown ? View.VISIBLE : View.GONE);
3656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public boolean getSpinnersShown() {
3696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return mSpinners.isShown();
3706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void onConfigurationChanged(Configuration newConfig) {
3746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        setCurrentLocale(newConfig.locale);
3756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public Parcelable onSaveInstanceState(Parcelable superState) {
3796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return new SavedState(superState, getYear(), getMonth(), getDayOfMonth(),
3806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                getMinDate().getTimeInMillis(), getMaxDate().getTimeInMillis());
3816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public void onRestoreInstanceState(Parcelable state) {
3856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (state instanceof SavedState) {
3866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            final SavedState ss = (SavedState) state;
3876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            setDate(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
3886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            updateSpinners();
3896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            updateCalendarView();
3906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
3916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
3946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
3956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        onPopulateAccessibilityEvent(event);
3966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return true;
3976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
3986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
3996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
4006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Sets the current locale.
4016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     *
4026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param locale The current locale.
4036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
4046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    @Override
4056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    protected void setCurrentLocale(Locale locale) {
4066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        super.setCurrentLocale(locale);
4076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mTempDate = getCalendarForLocale(mTempDate, locale);
4096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMinDate = getCalendarForLocale(mMinDate, locale);
4106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMaxDate = getCalendarForLocale(mMaxDate, locale);
4116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
4126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
4146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mShortMonths = new DateFormatSymbols().getShortMonths();
4156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (usingNumericMonths()) {
4176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            // We're in a locale where a date should either be all-numeric, or all-text.
4186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            // All-text would require custom NumberPicker formatters for day and year.
4196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mShortMonths = new String[mNumberOfMonths];
4206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            for (int i = 0; i < mNumberOfMonths; ++i) {
4216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mShortMonths[i] = String.format("%d", i + 1);
4226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
4236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
4246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
4256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
4276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Tests whether the current locale is one where there are no real month names,
4286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * such as Chinese, Japanese, or Korean locales.
4296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
4306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private boolean usingNumericMonths() {
4316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
4326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
4336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
4356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Gets a calendar for locale bootstrapped with the value of a given calendar.
4366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     *
4376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param oldCalendar The old calendar.
4386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param locale The locale.
4396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
4406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
4416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (oldCalendar == null) {
4426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return Calendar.getInstance(locale);
4436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
4446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            final long currentTimeMillis = oldCalendar.getTimeInMillis();
4456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            Calendar newCalendar = Calendar.getInstance(locale);
4466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            newCalendar.setTimeInMillis(currentTimeMillis);
4476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return newCalendar;
4486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
4496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
4506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
4526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Reorders the spinners according to the date format that is
4536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * explicitly set by the user and if no such is set fall back
4546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * to the current locale's default format.
4556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
4566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void reorderSpinners() {
4576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mSpinners.removeAllViews();
4586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // We use numeric spinners for year and day, but textual months. Ask icu4c what
4596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // order the user's locale uses for that combination. http://b/7207103.
4606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
4616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        char[] order = ICU.getDateFormatOrder(pattern);
4626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        final int spinnerCount = order.length;
4636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        for (int i = 0; i < spinnerCount; i++) {
4646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            switch (order[i]) {
4656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                case 'd':
4666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    mSpinners.addView(mDaySpinner);
4676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    setImeOptions(mDaySpinner, spinnerCount, i);
4686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    break;
4696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                case 'M':
4706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    mSpinners.addView(mMonthSpinner);
4716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    setImeOptions(mMonthSpinner, spinnerCount, i);
4726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    break;
4736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                case 'y':
4746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    mSpinners.addView(mYearSpinner);
4756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    setImeOptions(mYearSpinner, spinnerCount, i);
4766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    break;
4776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                default:
4786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    throw new IllegalArgumentException(Arrays.toString(order));
4796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
4806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
4816b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
4826b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4836b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
4846b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Parses the given <code>date</code> and in case of success sets the result
4856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * to the <code>outDate</code>.
4866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     *
4876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @return True if the date was parsed.
4886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
4896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private boolean parseDate(String date, Calendar outDate) {
4906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        try {
4916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            outDate.setTime(mDateFormat.parse(date));
4926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return true;
4936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } catch (ParseException e) {
4946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            e.printStackTrace();
4956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            return false;
4966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
4976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
4986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
4996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private boolean isNewDate(int year, int month, int dayOfMonth) {
5006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        return (mCurrentDate.get(Calendar.YEAR) != year
5016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                || mCurrentDate.get(Calendar.MONTH) != month
5026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                || mCurrentDate.get(Calendar.DAY_OF_MONTH) != dayOfMonth);
5036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
5046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void setDate(int year, int month, int dayOfMonth) {
5066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCurrentDate.set(year, month, dayOfMonth);
507f480e8cad5e6cf4fed85a944adc01d96f51e966bFelipe Leme        resetAutofilledValue();
5086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mCurrentDate.before(mMinDate)) {
5096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
5106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else if (mCurrentDate.after(mMaxDate)) {
5116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
5126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
5136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
5146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void updateSpinners() {
5166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // set the spinner ranges respecting the min and max dates
5176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mCurrentDate.equals(mMinDate)) {
5186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
5196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
5206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setWrapSelectorWheel(false);
5216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setDisplayedValues(null);
5226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
5236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
5246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setWrapSelectorWheel(false);
5256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else if (mCurrentDate.equals(mMaxDate)) {
5266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
5276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
5286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setWrapSelectorWheel(false);
5296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setDisplayedValues(null);
5306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
5316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
5326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setWrapSelectorWheel(false);
5336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
5346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMinValue(1);
5356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
5366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mDaySpinner.setWrapSelectorWheel(true);
5376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setDisplayedValues(null);
5386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMinValue(0);
5396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setMaxValue(11);
5406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinner.setWrapSelectorWheel(true);
5416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
5426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // make sure the month names are a zero based array
5446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // with the months in the month spinner
5456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        String[] displayedValues = Arrays.copyOfRange(mShortMonths,
5466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
5476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setDisplayedValues(displayedValues);
5486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // year spinner range does not change based on the current date
5506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
5516b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
5526b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setWrapSelectorWheel(false);
5536b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5546b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // set the spinner values
5556b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
5566b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
5576b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
5586b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5596b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (usingNumericMonths()) {
5606b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
5616b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
5626b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
5636b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5646b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
5656b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Updates the calendar view with the current date.
5666b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
5676b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void updateCalendarView() {
5686b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
5696b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
5706b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5716b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5726b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
5736b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Notifies the listener, if such, for a change in the selected date.
5746b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
5756b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void notifyDateChanged() {
5766b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
5776b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (mOnDateChangedListener != null) {
5786b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
5796b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                    getDayOfMonth());
5806b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
581305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        if (mAutoFillChangeListener != null) {
582305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme            mAutoFillChangeListener.onDateChanged(mDelegator, getYear(), getMonth(),
583305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme                    getDayOfMonth());
584305b72c92568a2dd2ece08caebd610ec8bd473f4Felipe Leme        }
5856b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
5866b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
5876b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    /**
5886b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * Sets the IME options for a spinner based on its ordering.
5896b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     *
5906b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param spinner The spinner.
5916b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param spinnerCount The total spinner count.
5926b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     * @param spinnerIndex The index of the given spinner.
5936b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette     */
5946b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
5956b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        final int imeOptions;
5966b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (spinnerIndex < spinnerCount - 1) {
5976b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            imeOptions = EditorInfo.IME_ACTION_NEXT;
5986b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        } else {
5996b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            imeOptions = EditorInfo.IME_ACTION_DONE;
6006b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
6016b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        TextView input = (TextView) spinner.findViewById(com.android.internal.R.id.numberpicker_input);
6026b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        input.setImeOptions(imeOptions);
6036b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
6046b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
6056b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void setContentDescriptions() {
6066b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // Day
6076b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mDaySpinner, com.android.internal.R.id.increment,
6086b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_increment_day_button);
6096b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mDaySpinner, com.android.internal.R.id.decrement,
6106b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_decrement_day_button);
6116b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // Month
6126b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mMonthSpinner, com.android.internal.R.id.increment,
6136b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_increment_month_button);
6146b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mMonthSpinner, com.android.internal.R.id.decrement,
6156b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_decrement_month_button);
6166b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // Year
6176b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mYearSpinner, com.android.internal.R.id.increment,
6186b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_increment_year_button);
6196b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        trySetContentDescription(mYearSpinner, com.android.internal.R.id.decrement,
6206b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                com.android.internal.R.string.date_picker_decrement_year_button);
6216b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
6226b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
6236b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void trySetContentDescription(View root, int viewId, int contDescResId) {
6246b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        View target = root.findViewById(viewId);
6256b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (target != null) {
6266b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            target.setContentDescription(mContext.getString(contDescResId));
6276b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
6286b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
6296b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette
6306b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    private void updateInputState() {
6316b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // Make sure that if the user changes the value and the IME is active
6326b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // for one of the inputs if this widget, the IME is closed. If the user
6336b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // changed the value via the IME and there is a next input the IME will
6346b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // be shown, otherwise the user chose another means of changing the
6356b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        // value and having the IME up makes no sense.
6366b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
6376b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        if (inputMethodManager != null) {
6386b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            if (inputMethodManager.isActive(mYearSpinnerInput)) {
6396b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mYearSpinnerInput.clearFocus();
6406b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
6416b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
6426b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mMonthSpinnerInput.clearFocus();
6436b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
6446b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
6456b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                mDaySpinnerInput.clearFocus();
6466b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
6476b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette            }
6486b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette        }
6496b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette    }
6506b3f85f87ed95cce748aeb57c70df0d2ed72707fAlan Viverette}
651