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
19cb3f2522609186db6239ad154af275957118295cSam Blitzsteinimport android.annotation.SuppressLint;
203e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.content.Context;
21385d36f15358e7d035b2e89e395588eb7952ebc2James Kungimport android.text.format.Time;
223e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.util.Log;
233e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.View;
243e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.ViewGroup;
253e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.widget.AbsListView.LayoutParams;
263e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.widget.BaseAdapter;
273e9818e0267619fecebd55095ab26c53eff92e93James Kung
28090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viveretteimport com.android.datetimepicker.date.SimpleMonthView.OnDayClickListener;
29090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverette
303e9818e0267619fecebd55095ab26c53eff92e93James Kungimport java.util.Calendar;
313e9818e0267619fecebd55095ab26c53eff92e93James Kungimport java.util.HashMap;
323e9818e0267619fecebd55095ab26c53eff92e93James Kung
333e9818e0267619fecebd55095ab26c53eff92e93James Kung/**
343e9818e0267619fecebd55095ab26c53eff92e93James Kung * An adapter for a list of {@link SimpleMonthView} items.
353e9818e0267619fecebd55095ab26c53eff92e93James Kung */
36090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverettepublic class SimpleMonthAdapter extends BaseAdapter implements OnDayClickListener {
373e9818e0267619fecebd55095ab26c53eff92e93James Kung
383e9818e0267619fecebd55095ab26c53eff92e93James Kung    private static final String TAG = "SimpleMonthAdapter";
393e9818e0267619fecebd55095ab26c53eff92e93James Kung
403e9818e0267619fecebd55095ab26c53eff92e93James Kung    private final Context mContext;
413e9818e0267619fecebd55095ab26c53eff92e93James Kung    private final DatePickerController mController;
423e9818e0267619fecebd55095ab26c53eff92e93James Kung
433e9818e0267619fecebd55095ab26c53eff92e93James Kung    private CalendarDay mSelectedDay;
443e9818e0267619fecebd55095ab26c53eff92e93James Kung
453e9818e0267619fecebd55095ab26c53eff92e93James Kung    protected static int WEEK_7_OVERHANG_HEIGHT = 7;
463e9818e0267619fecebd55095ab26c53eff92e93James Kung    protected static final int MONTHS_IN_YEAR = 12;
473e9818e0267619fecebd55095ab26c53eff92e93James Kung
483e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
493e9818e0267619fecebd55095ab26c53eff92e93James Kung     * A convenience class to represent a specific date.
503e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
513e9818e0267619fecebd55095ab26c53eff92e93James Kung    public static class CalendarDay {
523e9818e0267619fecebd55095ab26c53eff92e93James Kung        private Calendar calendar;
53385d36f15358e7d035b2e89e395588eb7952ebc2James Kung        private Time time;
543e9818e0267619fecebd55095ab26c53eff92e93James Kung        int year;
553e9818e0267619fecebd55095ab26c53eff92e93James Kung        int month;
563e9818e0267619fecebd55095ab26c53eff92e93James Kung        int day;
573e9818e0267619fecebd55095ab26c53eff92e93James Kung
583e9818e0267619fecebd55095ab26c53eff92e93James Kung        public CalendarDay() {
593e9818e0267619fecebd55095ab26c53eff92e93James Kung            setTime(System.currentTimeMillis());
603e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
613e9818e0267619fecebd55095ab26c53eff92e93James Kung
623e9818e0267619fecebd55095ab26c53eff92e93James Kung        public CalendarDay(long timeInMillis) {
633e9818e0267619fecebd55095ab26c53eff92e93James Kung            setTime(timeInMillis);
643e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
653e9818e0267619fecebd55095ab26c53eff92e93James Kung
663e9818e0267619fecebd55095ab26c53eff92e93James Kung        public CalendarDay(Calendar calendar) {
673e9818e0267619fecebd55095ab26c53eff92e93James Kung            year = calendar.get(Calendar.YEAR);
683e9818e0267619fecebd55095ab26c53eff92e93James Kung            month = calendar.get(Calendar.MONTH);
693e9818e0267619fecebd55095ab26c53eff92e93James Kung            day = calendar.get(Calendar.DAY_OF_MONTH);
703e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
713e9818e0267619fecebd55095ab26c53eff92e93James Kung
723e9818e0267619fecebd55095ab26c53eff92e93James Kung        public CalendarDay(int year, int month, int day) {
733e9818e0267619fecebd55095ab26c53eff92e93James Kung            setDay(year, month, day);
743e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
753e9818e0267619fecebd55095ab26c53eff92e93James Kung
763e9818e0267619fecebd55095ab26c53eff92e93James Kung        public void set(CalendarDay date) {
773e9818e0267619fecebd55095ab26c53eff92e93James Kung            year = date.year;
783e9818e0267619fecebd55095ab26c53eff92e93James Kung            month = date.month;
793e9818e0267619fecebd55095ab26c53eff92e93James Kung            day = date.day;
803e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
813e9818e0267619fecebd55095ab26c53eff92e93James Kung
823e9818e0267619fecebd55095ab26c53eff92e93James Kung        public void setDay(int year, int month, int day) {
833e9818e0267619fecebd55095ab26c53eff92e93James Kung            this.year = year;
843e9818e0267619fecebd55095ab26c53eff92e93James Kung            this.month = month;
853e9818e0267619fecebd55095ab26c53eff92e93James Kung            this.day = day;
863e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
873e9818e0267619fecebd55095ab26c53eff92e93James Kung
88385d36f15358e7d035b2e89e395588eb7952ebc2James Kung        public void setJulianDay(int julianDay) {
89385d36f15358e7d035b2e89e395588eb7952ebc2James Kung            if (time == null) {
90385d36f15358e7d035b2e89e395588eb7952ebc2James Kung                time = new Time();
91385d36f15358e7d035b2e89e395588eb7952ebc2James Kung            }
92385d36f15358e7d035b2e89e395588eb7952ebc2James Kung            time.setJulianDay(julianDay);
93385d36f15358e7d035b2e89e395588eb7952ebc2James Kung            setTime(time.toMillis(false));
94385d36f15358e7d035b2e89e395588eb7952ebc2James Kung        }
95385d36f15358e7d035b2e89e395588eb7952ebc2James Kung
963e9818e0267619fecebd55095ab26c53eff92e93James Kung        private void setTime(long timeInMillis) {
973e9818e0267619fecebd55095ab26c53eff92e93James Kung            if (calendar == null) {
983e9818e0267619fecebd55095ab26c53eff92e93James Kung                calendar = Calendar.getInstance();
993e9818e0267619fecebd55095ab26c53eff92e93James Kung            }
1003e9818e0267619fecebd55095ab26c53eff92e93James Kung            calendar.setTimeInMillis(timeInMillis);
1013e9818e0267619fecebd55095ab26c53eff92e93James Kung            month = calendar.get(Calendar.MONTH);
1023e9818e0267619fecebd55095ab26c53eff92e93James Kung            year = calendar.get(Calendar.YEAR);
1033e9818e0267619fecebd55095ab26c53eff92e93James Kung            day = calendar.get(Calendar.DAY_OF_MONTH);
1043e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1053e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1063e9818e0267619fecebd55095ab26c53eff92e93James Kung
1073e9818e0267619fecebd55095ab26c53eff92e93James Kung    public SimpleMonthAdapter(Context context,
1083e9818e0267619fecebd55095ab26c53eff92e93James Kung            DatePickerController controller) {
1093e9818e0267619fecebd55095ab26c53eff92e93James Kung        mContext = context;
1103e9818e0267619fecebd55095ab26c53eff92e93James Kung        mController = controller;
1113e9818e0267619fecebd55095ab26c53eff92e93James Kung        init();
1123e9818e0267619fecebd55095ab26c53eff92e93James Kung        setSelectedDay(mController.getSelectedDay());
1133e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1143e9818e0267619fecebd55095ab26c53eff92e93James Kung
1153e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
1163e9818e0267619fecebd55095ab26c53eff92e93James Kung     * Updates the selected day and related parameters.
1173e9818e0267619fecebd55095ab26c53eff92e93James Kung     *
118cb3f2522609186db6239ad154af275957118295cSam Blitzstein     * @param day The day to highlight
1193e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
1203e9818e0267619fecebd55095ab26c53eff92e93James Kung    public void setSelectedDay(CalendarDay day) {
1213e9818e0267619fecebd55095ab26c53eff92e93James Kung        mSelectedDay = day;
1223e9818e0267619fecebd55095ab26c53eff92e93James Kung        notifyDataSetChanged();
1233e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1243e9818e0267619fecebd55095ab26c53eff92e93James Kung
1253e9818e0267619fecebd55095ab26c53eff92e93James Kung    public CalendarDay getSelectedDay() {
1263e9818e0267619fecebd55095ab26c53eff92e93James Kung        return mSelectedDay;
1273e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1283e9818e0267619fecebd55095ab26c53eff92e93James Kung
1293e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
1303e9818e0267619fecebd55095ab26c53eff92e93James Kung     * Set up the gesture detector and selected time
1313e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
1323e9818e0267619fecebd55095ab26c53eff92e93James Kung    protected void init() {
1333e9818e0267619fecebd55095ab26c53eff92e93James Kung        mSelectedDay = new CalendarDay(System.currentTimeMillis());
1343e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1353e9818e0267619fecebd55095ab26c53eff92e93James Kung
1363e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1373e9818e0267619fecebd55095ab26c53eff92e93James Kung    public int getCount() {
138c9be9a5727eb272ad932be7dfaf41befde922268James Kung        return ((mController.getMaxYear() - mController.getMinYear()) + 1) * MONTHS_IN_YEAR;
1393e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1403e9818e0267619fecebd55095ab26c53eff92e93James Kung
1413e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1423e9818e0267619fecebd55095ab26c53eff92e93James Kung    public Object getItem(int position) {
1433e9818e0267619fecebd55095ab26c53eff92e93James Kung        return null;
1443e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1453e9818e0267619fecebd55095ab26c53eff92e93James Kung
1463e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1473e9818e0267619fecebd55095ab26c53eff92e93James Kung    public long getItemId(int position) {
1483e9818e0267619fecebd55095ab26c53eff92e93James Kung        return position;
1493e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1503e9818e0267619fecebd55095ab26c53eff92e93James Kung
151a35f6b580aefd7bf1c7e92306e13dacd44316714Alan Viverette    @Override
152a35f6b580aefd7bf1c7e92306e13dacd44316714Alan Viverette    public boolean hasStableIds() {
153a35f6b580aefd7bf1c7e92306e13dacd44316714Alan Viverette        return true;
154a35f6b580aefd7bf1c7e92306e13dacd44316714Alan Viverette    }
155a35f6b580aefd7bf1c7e92306e13dacd44316714Alan Viverette
156cb3f2522609186db6239ad154af275957118295cSam Blitzstein    @SuppressLint("NewApi")
1573e9818e0267619fecebd55095ab26c53eff92e93James Kung    @SuppressWarnings("unchecked")
1583e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1593e9818e0267619fecebd55095ab26c53eff92e93James Kung    public View getView(int position, View convertView, ViewGroup parent) {
1603e9818e0267619fecebd55095ab26c53eff92e93James Kung        SimpleMonthView v;
1613e9818e0267619fecebd55095ab26c53eff92e93James Kung        HashMap<String, Integer> drawingParams = null;
1623e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (convertView != null) {
1633e9818e0267619fecebd55095ab26c53eff92e93James Kung            v = (SimpleMonthView) convertView;
1643e9818e0267619fecebd55095ab26c53eff92e93James Kung            // We store the drawing parameters in the view so it can be recycled
1653e9818e0267619fecebd55095ab26c53eff92e93James Kung            drawingParams = (HashMap<String, Integer>) v.getTag();
1663e9818e0267619fecebd55095ab26c53eff92e93James Kung        } else {
1673e9818e0267619fecebd55095ab26c53eff92e93James Kung            v = new SimpleMonthView(mContext);
1683e9818e0267619fecebd55095ab26c53eff92e93James Kung            // Set up the new view
1693e9818e0267619fecebd55095ab26c53eff92e93James Kung            LayoutParams params = new LayoutParams(
1703e9818e0267619fecebd55095ab26c53eff92e93James Kung                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
1713e9818e0267619fecebd55095ab26c53eff92e93James Kung            v.setLayoutParams(params);
1723e9818e0267619fecebd55095ab26c53eff92e93James Kung            v.setClickable(true);
173090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverette            v.setOnDayClickListener(this);
1743e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1753e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (drawingParams == null) {
1763e9818e0267619fecebd55095ab26c53eff92e93James Kung            drawingParams = new HashMap<String, Integer>();
1773e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1783e9818e0267619fecebd55095ab26c53eff92e93James Kung        drawingParams.clear();
1793e9818e0267619fecebd55095ab26c53eff92e93James Kung
1803e9818e0267619fecebd55095ab26c53eff92e93James Kung        final int month = position % MONTHS_IN_YEAR;
1813e9818e0267619fecebd55095ab26c53eff92e93James Kung        final int year = position / MONTHS_IN_YEAR + mController.getMinYear();
1823e9818e0267619fecebd55095ab26c53eff92e93James Kung        Log.d(TAG, "Year: " + year + ", Month: " + month);
1833e9818e0267619fecebd55095ab26c53eff92e93James Kung
1843e9818e0267619fecebd55095ab26c53eff92e93James Kung        int selectedDay = -1;
1853e9818e0267619fecebd55095ab26c53eff92e93James Kung        if (isSelectedDayInMonth(year, month)) {
1863e9818e0267619fecebd55095ab26c53eff92e93James Kung            selectedDay = mSelectedDay.day;
1873e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
1883e9818e0267619fecebd55095ab26c53eff92e93James Kung
1893e9818e0267619fecebd55095ab26c53eff92e93James Kung        // Invokes requestLayout() to ensure that the recycled view is set with the appropriate
1903e9818e0267619fecebd55095ab26c53eff92e93James Kung        // height/number of weeks before being displayed.
1913e9818e0267619fecebd55095ab26c53eff92e93James Kung        v.reuse();
1923e9818e0267619fecebd55095ab26c53eff92e93James Kung
1933e9818e0267619fecebd55095ab26c53eff92e93James Kung        drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_DAY, selectedDay);
1943e9818e0267619fecebd55095ab26c53eff92e93James Kung        drawingParams.put(SimpleMonthView.VIEW_PARAMS_YEAR, year);
1953e9818e0267619fecebd55095ab26c53eff92e93James Kung        drawingParams.put(SimpleMonthView.VIEW_PARAMS_MONTH, month);
1963e9818e0267619fecebd55095ab26c53eff92e93James Kung        drawingParams.put(SimpleMonthView.VIEW_PARAMS_WEEK_START, mController.getFirstDayOfWeek());
1973e9818e0267619fecebd55095ab26c53eff92e93James Kung        v.setMonthParams(drawingParams);
1983e9818e0267619fecebd55095ab26c53eff92e93James Kung        v.invalidate();
1993e9818e0267619fecebd55095ab26c53eff92e93James Kung        return v;
2003e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2013e9818e0267619fecebd55095ab26c53eff92e93James Kung
2023e9818e0267619fecebd55095ab26c53eff92e93James Kung    private boolean isSelectedDayInMonth(int year, int month) {
2033e9818e0267619fecebd55095ab26c53eff92e93James Kung        return mSelectedDay.year == year && mSelectedDay.month == month;
2043e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2053e9818e0267619fecebd55095ab26c53eff92e93James Kung
206cb3f2522609186db6239ad154af275957118295cSam Blitzstein
2073e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
208090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverette    public void onDayClick(SimpleMonthView view, CalendarDay day) {
209090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverette        if (day != null) {
210090a46d6ee500d3674401fd3de48cd0f12ce7186Alan Viverette            onDayTapped(day);
2113e9818e0267619fecebd55095ab26c53eff92e93James Kung        }
2123e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2133e9818e0267619fecebd55095ab26c53eff92e93James Kung
2143e9818e0267619fecebd55095ab26c53eff92e93James Kung    /**
2153e9818e0267619fecebd55095ab26c53eff92e93James Kung     * Maintains the same hour/min/sec but moves the day to the tapped day.
2163e9818e0267619fecebd55095ab26c53eff92e93James Kung     *
2173e9818e0267619fecebd55095ab26c53eff92e93James Kung     * @param day The day that was tapped
2183e9818e0267619fecebd55095ab26c53eff92e93James Kung     */
2193e9818e0267619fecebd55095ab26c53eff92e93James Kung    protected void onDayTapped(CalendarDay day) {
2202e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mController.tryVibrate();
2212e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mController.onDayOfMonthSelected(day.year, day.month, day.day);
2223e9818e0267619fecebd55095ab26c53eff92e93James Kung        setSelectedDay(day);
2233e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
2243e9818e0267619fecebd55095ab26c53eff92e93James Kung}
225