DatePickerDialog.java revision f6de1f602ffac70987ebc9fc5e887494a23ddd35
13e9818e0267619fecebd55095ab26c53eff92e93James Kung/*
23e9818e0267619fecebd55095ab26c53eff92e93James Kung * Copyright (C) 2013 The Android Open Source Project
33e9818e0267619fecebd55095ab26c53eff92e93James Kung *
43e9818e0267619fecebd55095ab26c53eff92e93James Kung * Licensed under the Apache License, Version 2.0 (the "License");
53e9818e0267619fecebd55095ab26c53eff92e93James Kung * you may not use this file except in compliance with the License.
63e9818e0267619fecebd55095ab26c53eff92e93James Kung * You may obtain a copy of the License at
73e9818e0267619fecebd55095ab26c53eff92e93James Kung *
83e9818e0267619fecebd55095ab26c53eff92e93James Kung *      http://www.apache.org/licenses/LICENSE-2.0
93e9818e0267619fecebd55095ab26c53eff92e93James Kung *
103e9818e0267619fecebd55095ab26c53eff92e93James Kung * Unless required by applicable law or agreed to in writing, software
113e9818e0267619fecebd55095ab26c53eff92e93James Kung * distributed under the License is distributed on an "AS IS" BASIS,
123e9818e0267619fecebd55095ab26c53eff92e93James Kung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e9818e0267619fecebd55095ab26c53eff92e93James Kung * See the License for the specific language governing permissions and
143e9818e0267619fecebd55095ab26c53eff92e93James Kung * limitations under the License.
153e9818e0267619fecebd55095ab26c53eff92e93James Kung */
163e9818e0267619fecebd55095ab26c53eff92e93James Kung
173e9818e0267619fecebd55095ab26c53eff92e93James Kungpackage com.android.datetimepicker.date;
183e9818e0267619fecebd55095ab26c53eff92e93James Kung
193e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.app.Activity;
203e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.app.DialogFragment;
213e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.os.Bundle;
223e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.util.Log;
233e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.LayoutInflater;
243e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.View;
253e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.View.OnClickListener;
263e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.ViewGroup;
273e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.Window;
28f4d8e7a2271df7025f61d5ed086455a00b3fd325James Kungimport android.view.WindowManager;
29f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kungimport android.view.animation.AlphaAnimation;
30f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kungimport android.view.animation.Animation;
313e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.widget.Button;
32f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kungimport android.widget.LinearLayout;
333e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.widget.TextView;
34f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kungimport android.widget.ViewAnimator;
353e9818e0267619fecebd55095ab26c53eff92e93James Kung
363e9818e0267619fecebd55095ab26c53eff92e93James Kungimport com.android.datetimepicker.R;
373e9818e0267619fecebd55095ab26c53eff92e93James Kungimport com.android.datetimepicker.Utils;
383e9818e0267619fecebd55095ab26c53eff92e93James Kungimport com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
393e9818e0267619fecebd55095ab26c53eff92e93James Kung
403e9818e0267619fecebd55095ab26c53eff92e93James Kungimport java.text.SimpleDateFormat;
413e9818e0267619fecebd55095ab26c53eff92e93James Kungimport java.util.Calendar;
423e9818e0267619fecebd55095ab26c53eff92e93James Kungimport java.util.Locale;
433e9818e0267619fecebd55095ab26c53eff92e93James Kung
443e9818e0267619fecebd55095ab26c53eff92e93James Kung/**
453e9818e0267619fecebd55095ab26c53eff92e93James Kung * Dialog allowing users to select a date.
463e9818e0267619fecebd55095ab26c53eff92e93James Kung */
473e9818e0267619fecebd55095ab26c53eff92e93James Kungpublic class DatePickerDialog extends DialogFragment implements
48f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        OnClickListener, DatePickerController {
493e9818e0267619fecebd55095ab26c53eff92e93James Kung
503e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static final String TAG = "DatePickerDialog";
513e9818e0267619fecebd55095ab26c53eff92e93James Kung
52f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final int TOTAL_VIEWS = 2;
533e9818e0267619fecebd55095ab26c53eff92e93James Kung
54f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final int MONTH_AND_DAY_VIEW = 0;
55f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final int YEAR_VIEW = 1;
563e9818e0267619fecebd55095ab26c53eff92e93James Kung
57f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_SELECTED_YEAR = "year";
58f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_SELECTED_MONTH = "month";
59f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_SELECTED_DAY = "day";
60f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_LIST_POSITION = "position";
61f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_WEEK_START = "week_start";
62f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_YEAR_START = "year_start";
63f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_YEAR_END = "year_end";
64f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final String KEY_CURRENT_VIEW = "current_view";
653e9818e0267619fecebd55095ab26c53eff92e93James Kung
663e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static final int DEFAULT_START_YEAR = 1900;
673e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static final int DEFAULT_END_YEAR = 2100;
683e9818e0267619fecebd55095ab26c53eff92e93James Kung
69f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private static final int ANIMATION_DURATION = 500;
70f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung
713e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy", Locale.getDefault());
723e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd", Locale.getDefault());
733e9818e0267619fecebd55095ab26c53eff92e93James Kung
743e9818e0267619fecebd55095ab26c53eff92e93James Kung    private final Calendar mCalendar = Calendar.getInstance();
753e9818e0267619fecebd55095ab26c53eff92e93James Kung    private OnDateSetListener mCallBack;
763e9818e0267619fecebd55095ab26c53eff92e93James Kung
77f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private ViewAnimator mAnimator;
783e9818e0267619fecebd55095ab26c53eff92e93James Kung
793e9818e0267619fecebd55095ab26c53eff92e93James Kung    private TextView mDayOfWeekView;
80f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private LinearLayout mMonthAndDayView;
81f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private TextView mSelectedMonthTextView;
82f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private TextView mSelectedDayTextView;
833e9818e0267619fecebd55095ab26c53eff92e93James Kung    private TextView mYearView;
843e9818e0267619fecebd55095ab26c53eff92e93James Kung    private DayPickerView mDayPickerView;
853e9818e0267619fecebd55095ab26c53eff92e93James Kung    private YearPickerView mYearPickerView;
863e9818e0267619fecebd55095ab26c53eff92e93James Kung    private Button mDoneButton;
873e9818e0267619fecebd55095ab26c53eff92e93James Kung
88f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private int mCurrentView;
89f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung
903e9818e0267619fecebd55095ab26c53eff92e93James Kung    private int mWeekStart = mCalendar.getFirstDayOfWeek();
913e9818e0267619fecebd55095ab26c53eff92e93James Kung    private int mMinYear = DEFAULT_START_YEAR;
923e9818e0267619fecebd55095ab26c53eff92e93James Kung    private int mMaxYear = DEFAULT_END_YEAR;
933e9818e0267619fecebd55095ab26c53eff92e93James Kung
943e9818e0267619fecebd55095ab26c53eff92e93James Kung    private final View[] mViews = new View[TOTAL_VIEWS];
953e9818e0267619fecebd55095ab26c53eff92e93James Kung
963e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
973e9818e0267619fecebd55095ab26c53eff92e93James Kung     * The callback used to indicate the user is done filling in the date.
983e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
993e9818e0267619fecebd55095ab26c53eff92e93James Kung    public interface OnDateSetListener {
1003e9818e0267619fecebd55095ab26c53eff92e93James Kung
1013e9818e0267619fecebd55095ab26c53eff92e93James Kung        /**
1023e9818e0267619fecebd55095ab26c53eff92e93James Kung         * @param view The view associated with this listener.
1033e9818e0267619fecebd55095ab26c53eff92e93James Kung         * @param year The year that was set.
1043e9818e0267619fecebd55095ab26c53eff92e93James Kung         * @param monthOfYear The month that was set (0-11) for compatibility
1053e9818e0267619fecebd55095ab26c53eff92e93James Kung         *            with {@link java.util.Calendar}.
1063e9818e0267619fecebd55095ab26c53eff92e93James Kung         * @param dayOfMonth The day of the month that was set.
1073e9818e0267619fecebd55095ab26c53eff92e93James Kung         */
1083e9818e0267619fecebd55095ab26c53eff92e93James Kung        void onDateSet(DatePickerDialog dialog, int year, int monthOfYear, int dayOfMonth);
1093e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1103e9818e0267619fecebd55095ab26c53eff92e93James Kung
1113e9818e0267619fecebd55095ab26c53eff92e93James Kung    public DatePickerDialog() {
1123e9818e0267619fecebd55095ab26c53eff92e93James Kung        // Empty constructor required for dialog fragment.
1133e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1143e9818e0267619fecebd55095ab26c53eff92e93James Kung
1153e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
1163e9818e0267619fecebd55095ab26c53eff92e93James Kung     * @param callBack How the parent is notified that the date is set.
1173e9818e0267619fecebd55095ab26c53eff92e93James Kung     * @param year The initial year of the dialog.
1183e9818e0267619fecebd55095ab26c53eff92e93James Kung     * @param monthOfYear The initial month of the dialog.
1193e9818e0267619fecebd55095ab26c53eff92e93James Kung     * @param dayOfMonth The initial day of the dialog.
1203e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
1213e9818e0267619fecebd55095ab26c53eff92e93James Kung    public static DatePickerDialog newInstance(OnDateSetListener callBack, int year,
1223e9818e0267619fecebd55095ab26c53eff92e93James Kung            int monthOfYear,
1233e9818e0267619fecebd55095ab26c53eff92e93James Kung            int dayOfMonth) {
1243e9818e0267619fecebd55095ab26c53eff92e93James Kung        DatePickerDialog ret = new DatePickerDialog();
1253e9818e0267619fecebd55095ab26c53eff92e93James Kung        ret.initialize(callBack, year, monthOfYear, dayOfMonth);
1263e9818e0267619fecebd55095ab26c53eff92e93James Kung        return ret;
1273e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1283e9818e0267619fecebd55095ab26c53eff92e93James Kung
1293e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void initialize(OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
1303e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCallBack = callBack;
1313e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.YEAR, year);
1323e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.MONTH, monthOfYear);
1333e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
1343e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1353e9818e0267619fecebd55095ab26c53eff92e93James Kung
1363e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1373e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onCreate(Bundle savedInstanceState) {
1383e9818e0267619fecebd55095ab26c53eff92e93James Kung        super.onCreate(savedInstanceState);
139f4d8e7a2271df7025f61d5ed086455a00b3fd325James Kung        getActivity().getWindow().setSoftInputMode(
140f4d8e7a2271df7025f61d5ed086455a00b3fd325James Kung                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
1413e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (savedInstanceState != null) {
1423e9818e0267619fecebd55095ab26c53eff92e93James Kung            mCalendar.set(Calendar.YEAR, savedInstanceState.getInt(KEY_SELECTED_YEAR));
1433e9818e0267619fecebd55095ab26c53eff92e93James Kung            mCalendar.set(Calendar.MONTH, savedInstanceState.getInt(KEY_SELECTED_MONTH));
1443e9818e0267619fecebd55095ab26c53eff92e93James Kung            mCalendar.set(Calendar.DAY_OF_MONTH, savedInstanceState.getInt(KEY_SELECTED_DAY));
1453e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1463e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1473e9818e0267619fecebd55095ab26c53eff92e93James Kung
1483e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1493e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onSaveInstanceState(Bundle outState) {
1503e9818e0267619fecebd55095ab26c53eff92e93James Kung        super.onSaveInstanceState(outState);
1513e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_SELECTED_YEAR, mCalendar.get(Calendar.YEAR));
1523e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_SELECTED_MONTH, mCalendar.get(Calendar.MONTH));
1533e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_SELECTED_DAY, mCalendar.get(Calendar.DAY_OF_MONTH));
1543e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_LIST_POSITION, mDayPickerView.getFirstVisiblePosition());
1553e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_WEEK_START, mWeekStart);
1563e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_YEAR_START, mMinYear);
1573e9818e0267619fecebd55095ab26c53eff92e93James Kung        outState.putInt(KEY_YEAR_END, mMaxYear);
158f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        outState.putInt(KEY_CURRENT_VIEW, mCurrentView);
1593e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1603e9818e0267619fecebd55095ab26c53eff92e93James Kung
1613e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1623e9818e0267619fecebd55095ab26c53eff92e93James Kung    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1633e9818e0267619fecebd55095ab26c53eff92e93James Kung            Bundle savedInstanceState) {
1643e9818e0267619fecebd55095ab26c53eff92e93James Kung        Log.d(TAG, "onCreateView: ");
1653e9818e0267619fecebd55095ab26c53eff92e93James Kung        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
1663e9818e0267619fecebd55095ab26c53eff92e93James Kung
1673e9818e0267619fecebd55095ab26c53eff92e93James Kung        View view = inflater.inflate(R.layout.date_picker_dialog, null);
1683e9818e0267619fecebd55095ab26c53eff92e93James Kung
1693e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDayOfWeekView = (TextView) view.findViewById(R.id.date_picker_header);
170f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mMonthAndDayView = (LinearLayout) view.findViewById(R.id.date_picker_month_and_day);
171f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mMonthAndDayView.setOnClickListener(this);
172f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mSelectedMonthTextView = (TextView) view.findViewById(R.id.date_picker_month);
173f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mSelectedDayTextView = (TextView) view.findViewById(R.id.date_picker_day);
1743e9818e0267619fecebd55095ab26c53eff92e93James Kung        mYearView = (TextView) view.findViewById(R.id.date_picker_year);
1753e9818e0267619fecebd55095ab26c53eff92e93James Kung        mYearView.setOnClickListener(this);
1763e9818e0267619fecebd55095ab26c53eff92e93James Kung        final Activity activity = getActivity();
1773e9818e0267619fecebd55095ab26c53eff92e93James Kung
178f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        int currentView = MONTH_AND_DAY_VIEW;
1793e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDayPickerView = new DayPickerView(activity, this);
1803e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (savedInstanceState != null) {
1813e9818e0267619fecebd55095ab26c53eff92e93James Kung            Log.d(TAG,
1823e9818e0267619fecebd55095ab26c53eff92e93James Kung                    "Setting first visible position: "
1833e9818e0267619fecebd55095ab26c53eff92e93James Kung                            + savedInstanceState.getInt(KEY_LIST_POSITION));
1843e9818e0267619fecebd55095ab26c53eff92e93James Kung            mDayPickerView.setSelectionFromTop(savedInstanceState.getInt(KEY_LIST_POSITION),
1853e9818e0267619fecebd55095ab26c53eff92e93James Kung                    DayPickerView.LIST_TOP_OFFSET);
1863e9818e0267619fecebd55095ab26c53eff92e93James Kung            mWeekStart = savedInstanceState.getInt(KEY_WEEK_START);
1873e9818e0267619fecebd55095ab26c53eff92e93James Kung            mMinYear = savedInstanceState.getInt(KEY_YEAR_START);
1883e9818e0267619fecebd55095ab26c53eff92e93James Kung            mMaxYear = savedInstanceState.getInt(KEY_YEAR_END);
189f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung            currentView = savedInstanceState.getInt(KEY_CURRENT_VIEW);
1903e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1913e9818e0267619fecebd55095ab26c53eff92e93James Kung        mYearPickerView = new YearPickerView(activity, this);
1923e9818e0267619fecebd55095ab26c53eff92e93James Kung
193f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mViews[MONTH_AND_DAY_VIEW] = mDayPickerView;
1943e9818e0267619fecebd55095ab26c53eff92e93James Kung        mViews[YEAR_VIEW] = mYearPickerView;
1953e9818e0267619fecebd55095ab26c53eff92e93James Kung
196f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mAnimator = (ViewAnimator) view.findViewById(R.id.animator);
197f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        // TODO: Replace with animation decided upon by the design team.
198f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        Animation animation = new AlphaAnimation(0.0f, 1.0f);
199f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        animation.setDuration(ANIMATION_DURATION);
200f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mAnimator.setInAnimation(animation);
201f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        // TODO: Replace with animation decided upon by the design team.
202f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
203f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        animation2.setDuration(ANIMATION_DURATION);
204f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mAnimator.setOutAnimation(animation2);
205f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mAnimator.addView(mDayPickerView);
206f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mAnimator.addView(mYearPickerView);
2073e9818e0267619fecebd55095ab26c53eff92e93James Kung
2083e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDoneButton = (Button) view.findViewById(R.id.done);
2093e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDoneButton.setOnClickListener(new OnClickListener() {
2103e9818e0267619fecebd55095ab26c53eff92e93James Kung
2113e9818e0267619fecebd55095ab26c53eff92e93James Kung            @Override
2123e9818e0267619fecebd55095ab26c53eff92e93James Kung            public void onClick(View v) {
2133e9818e0267619fecebd55095ab26c53eff92e93James Kung                if (mCallBack != null) {
2143e9818e0267619fecebd55095ab26c53eff92e93James Kung                    mCallBack.onDateSet(DatePickerDialog.this, mCalendar.get(Calendar.YEAR),
2153e9818e0267619fecebd55095ab26c53eff92e93James Kung                            mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
2163e9818e0267619fecebd55095ab26c53eff92e93James Kung                }
2173e9818e0267619fecebd55095ab26c53eff92e93James Kung                dismiss();
2183e9818e0267619fecebd55095ab26c53eff92e93James Kung            }
2193e9818e0267619fecebd55095ab26c53eff92e93James Kung        });
2203e9818e0267619fecebd55095ab26c53eff92e93James Kung
2213e9818e0267619fecebd55095ab26c53eff92e93James Kung        updateDisplay();
222f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        setCurrentView(currentView);
2233e9818e0267619fecebd55095ab26c53eff92e93James Kung
2243e9818e0267619fecebd55095ab26c53eff92e93James Kung        return view;
2253e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2263e9818e0267619fecebd55095ab26c53eff92e93James Kung
227f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    private void setCurrentView(final int viewIndex) {
228f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        switch (viewIndex) {
229f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung            case MONTH_AND_DAY_VIEW:
230f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mCurrentView = viewIndex;
231f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mMonthAndDayView.setSelected(true);
232f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mYearView.setSelected(false);
233f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
234f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                break;
235f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung            case YEAR_VIEW:
236f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mCurrentView = viewIndex;
237f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mMonthAndDayView.setSelected(false);
238f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mYearView.setSelected(true);
239f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                mAnimator.setDisplayedChild(YEAR_VIEW);
240f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung                break;
241f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        }
242f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung    }
243f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung
2443e9818e0267619fecebd55095ab26c53eff92e93James Kung    private void updateDisplay() {
2453e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDayOfWeekView.setText(mCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
2463e9818e0267619fecebd55095ab26c53eff92e93James Kung                Locale.getDefault()).toUpperCase(Locale.getDefault()));
247f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mSelectedMonthTextView.setText(mCalendar.getDisplayName(Calendar.MONTH, Calendar.SHORT,
2483e9818e0267619fecebd55095ab26c53eff92e93James Kung                Locale.getDefault()).toUpperCase(Locale.getDefault()));
249f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        mSelectedDayTextView.setText(DAY_FORMAT.format(mCalendar.getTime()));
2503e9818e0267619fecebd55095ab26c53eff92e93James Kung        mYearView.setText(YEAR_FORMAT.format(mCalendar.getTime()));
2513e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2523e9818e0267619fecebd55095ab26c53eff92e93James Kung
2533e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void setFirstDayOfWeek(int startOfWeek) {
2543e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (startOfWeek < Calendar.SUNDAY || startOfWeek > Calendar.SATURDAY) {
2553e9818e0267619fecebd55095ab26c53eff92e93James Kung            throw new IllegalArgumentException("Value must be between Calendar.SUNDAY and " +
2563e9818e0267619fecebd55095ab26c53eff92e93James Kung                    "Calendar.SATURDAY");
2573e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2583e9818e0267619fecebd55095ab26c53eff92e93James Kung        mWeekStart = startOfWeek;
2593e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (mDayPickerView != null) {
2603e9818e0267619fecebd55095ab26c53eff92e93James Kung            mDayPickerView.onChange();
2613e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2623e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2633e9818e0267619fecebd55095ab26c53eff92e93James Kung
2643e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void setYearRange(int startYear, int endYear) {
2653e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (endYear <= startYear) {
2663e9818e0267619fecebd55095ab26c53eff92e93James Kung            throw new IllegalArgumentException("Year end must be larger than year start");
2673e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2683e9818e0267619fecebd55095ab26c53eff92e93James Kung        mMinYear = startYear;
2693e9818e0267619fecebd55095ab26c53eff92e93James Kung        mMaxYear = endYear;
2703e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (mDayPickerView != null) {
2713e9818e0267619fecebd55095ab26c53eff92e93James Kung            mDayPickerView.onChange();
2723e9818e0267619fecebd55095ab26c53eff92e93James Kung            mYearPickerView.onChange();
2733e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2743e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2753e9818e0267619fecebd55095ab26c53eff92e93James Kung
2763e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void setOnDateSetListener(OnDateSetListener listener) {
2773e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCallBack = listener;
2783e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2793e9818e0267619fecebd55095ab26c53eff92e93James Kung
2803e9818e0267619fecebd55095ab26c53eff92e93James Kung    // If the newly selected month / year does not contain the currently selected day number,
2813e9818e0267619fecebd55095ab26c53eff92e93James Kung    // change the selected day number to the last day of the selected month or year.
2823e9818e0267619fecebd55095ab26c53eff92e93James Kung    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
2833e9818e0267619fecebd55095ab26c53eff92e93James Kung    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
2843e9818e0267619fecebd55095ab26c53eff92e93James Kung    private void adjustDayInMonthIfNeeded(int month, int year) {
2853e9818e0267619fecebd55095ab26c53eff92e93James Kung        int day = mCalendar.get(Calendar.DAY_OF_MONTH);
2863e9818e0267619fecebd55095ab26c53eff92e93James Kung        int daysInMonth = Utils.getDaysInMonth(month, year);
2873e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (day > daysInMonth) {
2883e9818e0267619fecebd55095ab26c53eff92e93James Kung            mCalendar.set(Calendar.DAY_OF_MONTH, daysInMonth);
2893e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2903e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2913e9818e0267619fecebd55095ab26c53eff92e93James Kung
2923e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
2933e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onClick(View v) {
2943e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (v.getId() == R.id.date_picker_year) {
295f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung            setCurrentView(YEAR_VIEW);
296f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        } else if (v.getId() == R.id.date_picker_month_and_day) {
297f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung            setCurrentView(MONTH_AND_DAY_VIEW);
2983e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2993e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3003e9818e0267619fecebd55095ab26c53eff92e93James Kung
3013e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3023e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onYearPickerSelectionChanged(int year) {
3033e9818e0267619fecebd55095ab26c53eff92e93James Kung        adjustDayInMonthIfNeeded(mCalendar.get(Calendar.MONTH), year);
3043e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.YEAR, year);
3053e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDayPickerView.setCalendarDate(getSelectedDay());
3063e9818e0267619fecebd55095ab26c53eff92e93James Kung        updateDisplay();
3073e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3083e9818e0267619fecebd55095ab26c53eff92e93James Kung
3093e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3103e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onMonthPickerSelectionChanged(int month) {
3113e9818e0267619fecebd55095ab26c53eff92e93James Kung        adjustDayInMonthIfNeeded(month, mCalendar.get(Calendar.YEAR));
3123e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.MONTH, month);
3133e9818e0267619fecebd55095ab26c53eff92e93James Kung        mDayPickerView.setCalendarDate(getSelectedDay());
314f6de1f602ffac70987ebc9fc5e887494a23ddd35James Kung        setCurrentView(MONTH_AND_DAY_VIEW);
3153e9818e0267619fecebd55095ab26c53eff92e93James Kung        updateDisplay();
3163e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3173e9818e0267619fecebd55095ab26c53eff92e93James Kung
3183e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3193e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void onDayPickerSelectionChanged(int year, int month, int day) {
3203e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.YEAR, year);
3213e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.MONTH, month);
3223e9818e0267619fecebd55095ab26c53eff92e93James Kung        mCalendar.set(Calendar.DAY_OF_MONTH, day);
3233e9818e0267619fecebd55095ab26c53eff92e93James Kung        mYearPickerView.setValue(mCalendar.get(Calendar.YEAR));
3243e9818e0267619fecebd55095ab26c53eff92e93James Kung        updateDisplay();
3253e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3263e9818e0267619fecebd55095ab26c53eff92e93James Kung
3273e9818e0267619fecebd55095ab26c53eff92e93James Kung
3283e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3293e9818e0267619fecebd55095ab26c53eff92e93James Kung    public CalendarDay getSelectedDay() {
3303e9818e0267619fecebd55095ab26c53eff92e93James Kung        return new CalendarDay(mCalendar);
3313e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3323e9818e0267619fecebd55095ab26c53eff92e93James Kung
3333e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3343e9818e0267619fecebd55095ab26c53eff92e93James Kung    public int getMinYear() {
3353e9818e0267619fecebd55095ab26c53eff92e93James Kung        return mMinYear;
3363e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3373e9818e0267619fecebd55095ab26c53eff92e93James Kung
3383e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3393e9818e0267619fecebd55095ab26c53eff92e93James Kung    public int getMaxYear() {
3403e9818e0267619fecebd55095ab26c53eff92e93James Kung        return mMaxYear;
3413e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3423e9818e0267619fecebd55095ab26c53eff92e93James Kung
3433e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
3443e9818e0267619fecebd55095ab26c53eff92e93James Kung    public int getFirstDayOfWeek() {
3453e9818e0267619fecebd55095ab26c53eff92e93James Kung        return mWeekStart;
3463e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
3473e9818e0267619fecebd55095ab26c53eff92e93James Kung}
348