DatePicker.java revision 5fe1e6221ea3bab3120f5b9c0ceacaf59d116c05
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.Widget;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.DateFormat;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
2868f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrookimport android.widget.NumberPicker;
2968f2f547f56f239b60d13b2b62a08a65874f6662Paul Westbrookimport android.widget.NumberPicker.OnChangedListener;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.text.DateFormatSymbols;
3403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischerimport java.text.SimpleDateFormat;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view for selecting a month / year / day based on a calendar like layout.
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For a dialog using this view, see {@link android.app.DatePickerDialog}.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@Widget
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatePicker extends FrameLayout {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DEFAULT_START_YEAR = 1900;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DEFAULT_END_YEAR = 2100;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* UI Components */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final NumberPicker mDayPicker;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final NumberPicker mMonthPicker;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final NumberPicker mYearPicker;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * How we notify users the date has changed.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDateChangedListener mOnDateChangedListener;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mDay;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mMonth;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mYear;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The callback used to indicate the user changes the date.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDateChangedListener {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param view The view associated with this listener.
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param year The year that was set.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param monthOfYear The month that was set (0-11) for compatibility
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  with {@link java.util.Calendar}.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dayOfMonth The day of the month that was set.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, 0);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public DatePicker(Context context, AttributeSet attrs, int defStyle) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs, defStyle);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater.inflate(R.layout.date_picker, this, true);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker = (NumberPicker) findViewById(R.id.day);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setSpeed(100);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setOnChangeListener(new OnChangedListener() {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDay = newVal;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mOnDateChangedListener != null) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker = (NumberPicker) findViewById(R.id.month);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DateFormatSymbols dfs = new DateFormatSymbols();
10503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        String[] months = dfs.getShortMonths();
1065fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer
1075fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer        /*
1085fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer         * If the user is in a locale where the month names are numeric,
1095fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer         * use just the number instead of the "month" character for
1105fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer         * consistency with the other fields.
1115fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer         */
1125fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer        if (months[0].startsWith("1")) {
1135fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer            for (int i = 0; i < months.length; i++) {
1145fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer                months[i] = String.valueOf(i + 1);
1155fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer            }
1165fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer        }
1175fe1e6221ea3bab3120f5b9c0ceacaf59d116c05Eric Fischer
11803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        mMonthPicker.setRange(1, 12, months);
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker.setSpeed(200);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker.setOnChangeListener(new OnChangedListener() {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* We display the month 1-12 but store it 0-11 so always
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 * subtract by one to ensure our internal state is always 0-11
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 */
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mMonth = newVal - 1;
1272bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu                // Adjust max day of the month
1282bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu                adjustMaxDay();
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mOnDateChangedListener != null) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updateDaySpinner();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker = (NumberPicker) findViewById(R.id.year);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker.setSpeed(100);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker.setOnChangeListener(new OnChangedListener() {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void onChanged(NumberPicker picker, int oldVal, int newVal) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mYear = newVal;
1402bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu                // Adjust max day for leap years if needed
1412bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu                adjustMaxDay();
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mOnDateChangedListener != null) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1452bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu                updateDaySpinner();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // attributes
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker.setRange(mStartYear, mEndYear);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // initialize to current date
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Calendar cal = Calendar.getInstance();
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // re-order the number pickers to match the current date format
16303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        reorderPickers(months);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isEnabled()) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setEnabled(false);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setEnabled(boolean enabled) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setEnabled(enabled);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setEnabled(enabled);
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker.setEnabled(enabled);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker.setEnabled(enabled);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer    private void reorderPickers(String[] months) {
17903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        java.text.DateFormat format;
18003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        String order;
18103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
18203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        /*
18303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer         * If the user is in a locale where the medium date format is
18403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer         * still numeric (Japanese and Czech, for example), respect
18503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer         * the date format order setting.  Otherwise, use the order
18603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer         * that the locale says is appropriate for a spelled-out date.
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
18803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
18903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        if (months[0].startsWith("1")) {
19003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            format = DateFormat.getDateFormat(getContext());
19103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        } else {
19203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            format = DateFormat.getMediumDateFormat(getContext());
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
19503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        if (format instanceof SimpleDateFormat) {
19603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            order = ((SimpleDateFormat) format).toPattern();
19703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        } else {
19803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            // Shouldn't happen, but just in case.
19903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            order = new String(DateFormat.getDateFormatOrder(getContext()));
20003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        }
20103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* Remove the 3 pickers from their parent and then add them back in the
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * required order.
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parent.removeAllViews();
20703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
20803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        boolean quoted = false;
20903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        boolean didDay = false, didMonth = false, didYear = false;
21003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
21103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        for (int i = 0; i < order.length(); i++) {
21203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            char c = order.charAt(i);
21303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
21403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            if (c == '\'') {
21503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                quoted = !quoted;
21603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            }
21703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
21803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            if (!quoted) {
21903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                if (c == DateFormat.DATE && !didDay) {
22003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    parent.addView(mDayPicker);
22103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    didDay = true;
22203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) {
22303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    parent.addView(mMonthPicker);
22403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    didMonth = true;
22503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                } else if (c == DateFormat.YEAR && !didYear) {
22603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    parent.addView (mYearPicker);
22703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                    didYear = true;
22803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer                }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer
23203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        // Shouldn't happen, but just in case.
23303a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        if (!didMonth) {
23403a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            parent.addView(mMonthPicker);
23503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        }
23603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        if (!didDay) {
23703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            parent.addView(mDayPicker);
23803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        }
23903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        if (!didYear) {
24003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer            parent.addView(mYearPicker);
24103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateDate(int year, int monthOfYear, int dayOfMonth) {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYear = year;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonth = monthOfYear;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDay = dayOfMonth;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateSpinners();
24903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer        reorderPickers(new DateFormatSymbols().getShortMonths());
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class SavedState extends BaseSavedState {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final int mYear;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final int mMonth;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final int mDay;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link DatePicker#onSaveInstanceState()}
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private SavedState(Parcelable superState, int year, int month, int day) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(superState);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mYear = year;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMonth = month;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDay = day;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link #CREATOR}
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private SavedState(Parcel in) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(in);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mYear = in.readInt();
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMonth = in.readInt();
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDay = in.readInt();
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getYear() {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mYear;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getMonth() {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mMonth;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getDay() {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDay;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.writeToParcel(dest, flags);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(mYear);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(mMonth);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(mDay);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final Parcelable.Creator<SavedState> CREATOR =
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new Creator<SavedState>() {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    public SavedState createFromParcel(Parcel in) {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return new SavedState(in);
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    public SavedState[] newArray(int size) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return new SavedState[size];
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                };
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override so we are in complete control of save / restore for this widget.
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dispatchThawSelfOnly(container);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Parcelable onSaveInstanceState() {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcelable superState = super.onSaveInstanceState();
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new SavedState(superState, mYear, mMonth, mDay);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onRestoreInstanceState(Parcelable state) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SavedState ss = (SavedState) state;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onRestoreInstanceState(ss.getSuperState());
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYear = ss.getYear();
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonth = ss.getMonth();
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDay = ss.getDay();
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Initialize the state.
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param year The initial year.
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param monthOfYear The initial month.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dayOfMonth The initial day of the month.
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDateChangedListener How user is notified date is changed by user, can be null.
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void init(int year, int monthOfYear, int dayOfMonth,
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OnDateChangedListener onDateChangedListener) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYear = year;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonth = monthOfYear;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDay = dayOfMonth;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDateChangedListener = onDateChangedListener;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateSpinners();
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void updateSpinners() {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateDaySpinner();
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mYearPicker.setCurrent(mYear);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* The month display uses 1-12 but our internal state stores it
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * 0-11 so add one when setting the display.
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMonthPicker.setCurrent(mMonth + 1);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void updateDaySpinner() {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Calendar cal = Calendar.getInstance();
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cal.set(mYear, mMonth, mDay);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setRange(1, max);
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDayPicker.setCurrent(mDay);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getYear() {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mYear;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMonth() {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mMonth;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getDayOfMonth() {
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDay;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3812bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu
3822bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu    private void adjustMaxDay(){
3832bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        Calendar cal = Calendar.getInstance();
3842bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        cal.set(Calendar.YEAR, mYear);
3852bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        cal.set(Calendar.MONTH, mMonth);
3862bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
3872bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        if (mDay > max) {
3882bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu            mDay = max;
3892bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu        }
3902bf761c20253222a763bce9a63d14c48ab08a556Suchi Amalapurapu    }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
392