10ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette/*
20ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Copyright (C) 2015 The Android Open Source Project
30ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette *
40ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License");
50ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * you may not use this file except in compliance with the License.
60ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * You may obtain a copy of the License at
70ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette *
80ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette *      http://www.apache.org/licenses/LICENSE-2.0
90ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette *
100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Unless required by applicable law or agreed to in writing, software
110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS,
120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * See the License for the specific language governing permissions and
140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * limitations under the License.
150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */
160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverettepackage android.widget;
180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport com.android.internal.widget.PagerAdapter;
200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.IdRes;
2260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.LayoutRes;
2360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.NonNull;
2460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.Nullable;
250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.Context;
260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.res.ColorStateList;
270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.res.TypedArray;
2868763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar;
290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.util.SparseArray;
3060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.view.LayoutInflater;
310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.View;
320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.ViewGroup;
330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.SimpleMonthView.OnDayClickListener;
340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette/**
360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * An adapter for a list of {@link android.widget.SimpleMonthView} items.
370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */
3878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteclass DayPickerPagerAdapter extends PagerAdapter {
390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private static final int MONTHS_IN_YEAR = 12;
400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final Calendar mMinDate = Calendar.getInstance();
420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final Calendar mMaxDate = Calendar.getInstance();
430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
4460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private final SparseArray<ViewHolder> mItems = new SparseArray<>();
450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
4660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private final LayoutInflater mInflater;
4760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private final int mLayoutResId;
4860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private final int mCalendarViewId;
4960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
5060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private Calendar mSelectedDay = null;
510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int mMonthTextAppearance;
530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int mDayOfWeekTextAppearance;
540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int mDayTextAppearance;
550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ColorStateList mCalendarTextColor;
570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ColorStateList mDaySelectorColor;
580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private ColorStateList mDayHighlightColor;
590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private OnDaySelectedListener mOnDaySelectedListener;
610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
6260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private int mCount;
630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int mFirstDayOfWeek;
640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
6578bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette    public DayPickerPagerAdapter(@NonNull Context context, @LayoutRes int layoutResId,
6660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            @IdRes int calendarViewId) {
6760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        mInflater = LayoutInflater.from(context);
6860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        mLayoutResId = layoutResId;
6960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        mCalendarViewId = calendarViewId;
7060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final TypedArray ta = context.obtainStyledAttributes(new int[] {
720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                com.android.internal.R.attr.colorControlHighlight});
730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDayHighlightColor = ta.getColorStateList(0);
740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        ta.recycle();
750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
7760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    public void setRange(@NonNull Calendar min, @NonNull Calendar max) {
780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mMinDate.setTimeInMillis(min.getTimeInMillis());
790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mMaxDate.setTimeInMillis(max.getTimeInMillis());
800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
8160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
8260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final int diffMonth = mMaxDate.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
8360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        mCount = diffMonth + MONTHS_IN_YEAR * diffYear + 1;
8460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Positions are now invalid, clear everything and start over.
860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        notifyDataSetChanged();
870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Sets the first day of the week.
910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *
920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * @param weekStart which day the week should start on, valid values are
930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *                  {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY}
940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public void setFirstDayOfWeek(int weekStart) {
960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mFirstDayOfWeek = weekStart;
970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Update displayed views.
990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int count = mItems.size();
1000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        for (int i = 0; i < count; i++) {
10160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            final SimpleMonthView monthView = mItems.valueAt(i).calendar;
1020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            monthView.setFirstDayOfWeek(weekStart);
1030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
1040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public int getFirstDayOfWeek() {
1070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return mFirstDayOfWeek;
1080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
1110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Sets the selected day.
1120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *
1130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * @param day the selected day
1140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
11560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    public void setSelectedDay(@Nullable Calendar day) {
1160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int oldPosition = getPositionForDay(mSelectedDay);
1170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int newPosition = getPositionForDay(day);
1180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Clear the old position if necessary.
12060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        if (oldPosition != newPosition && oldPosition >= 0) {
12160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            final ViewHolder oldMonthView = mItems.get(oldPosition, null);
1220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            if (oldMonthView != null) {
12360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette                oldMonthView.calendar.setSelectedDay(-1);
1240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            }
1250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
1260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        // Set the new position.
12860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        if (newPosition >= 0) {
12960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            final ViewHolder newMonthView = mItems.get(newPosition, null);
13060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            if (newMonthView != null) {
13160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette                final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH);
13260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette                newMonthView.calendar.setSelectedDay(dayOfMonth);
13360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            }
1340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
1350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mSelectedDay = day;
1370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    /**
1400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * Sets the listener to call when the user selects a day.
1410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     *
1420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     * @param listener The listener to call.
1430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette     */
1440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public void setOnDaySelectedListener(OnDaySelectedListener listener) {
1450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mOnDaySelectedListener = listener;
1460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    void setCalendarTextColor(ColorStateList calendarTextColor) {
1490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mCalendarTextColor = calendarTextColor;
150d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette        notifyDataSetChanged();
1510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    void setDaySelectorColor(ColorStateList selectorColor) {
1540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDaySelectorColor = selectorColor;
155d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette        notifyDataSetChanged();
1560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    void setMonthTextAppearance(int resId) {
1590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mMonthTextAppearance = resId;
160d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette        notifyDataSetChanged();
1610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    void setDayOfWeekTextAppearance(int resId) {
1640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDayOfWeekTextAppearance = resId;
165d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette        notifyDataSetChanged();
1660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    int getDayOfWeekTextAppearance() {
1690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return mDayOfWeekTextAppearance;
1700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    void setDayTextAppearance(int resId) {
1730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mDayTextAppearance = resId;
174d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette        notifyDataSetChanged();
1750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    int getDayTextAppearance() {
1780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return mDayTextAppearance;
1790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
1820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public int getCount() {
18360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        return mCount;
1840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
1870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public boolean isViewFromObject(View view, Object object) {
18860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final ViewHolder holder = (ViewHolder) object;
18960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        return view == holder.container;
1900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int getMonthForPosition(int position) {
193bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette        return (position + mMinDate.get(Calendar.MONTH)) % MONTHS_IN_YEAR;
1940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
1950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
1960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private int getYearForPosition(int position) {
197bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette        final int yearOffset = (position + mMinDate.get(Calendar.MONTH)) / MONTHS_IN_YEAR;
198bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette        return yearOffset + mMinDate.get(Calendar.YEAR);
1990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
20160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private int getPositionForDay(@Nullable Calendar day) {
20260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        if (day == null) {
20360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            return -1;
20460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        }
20560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
206bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette        final int yearOffset = day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
207bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette        final int monthOffset = day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
20878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette        final int position = yearOffset * MONTHS_IN_YEAR + monthOffset;
20978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette        return position;
2100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
2130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public Object instantiateItem(ViewGroup container, int position) {
21460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final View itemView = mInflater.inflate(mLayoutResId, container, false);
21560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
21660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final SimpleMonthView v = (SimpleMonthView) itemView.findViewById(mCalendarViewId);
2170ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        v.setOnDayClickListener(mOnDayClickListener);
2180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        v.setMonthTextAppearance(mMonthTextAppearance);
2190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance);
2200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        v.setDayTextAppearance(mDayTextAppearance);
2210ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mDaySelectorColor != null) {
2230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            v.setDaySelectorColor(mDaySelectorColor);
2240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mDayHighlightColor != null) {
2270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            v.setDayHighlightColor(mDayHighlightColor);
2280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mCalendarTextColor != null) {
2310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            v.setMonthTextColor(mCalendarTextColor);
2320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            v.setDayOfWeekTextColor(mCalendarTextColor);
2330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            v.setDayTextColor(mCalendarTextColor);
2340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int month = getMonthForPosition(position);
2370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int year = getYearForPosition(position);
2380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int selectedDay;
24060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        if (mSelectedDay != null && mSelectedDay.get(Calendar.MONTH) == month) {
2410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH);
2420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        } else {
2430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            selectedDay = -1;
2440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int enabledDayRangeStart;
2470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mMinDate.get(Calendar.MONTH) == month && mMinDate.get(Calendar.YEAR) == year) {
2480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            enabledDayRangeStart = mMinDate.get(Calendar.DAY_OF_MONTH);
2490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        } else {
2500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            enabledDayRangeStart = 1;
2510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        final int enabledDayRangeEnd;
2540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (mMaxDate.get(Calendar.MONTH) == month && mMaxDate.get(Calendar.YEAR) == year) {
2550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            enabledDayRangeEnd = mMaxDate.get(Calendar.DAY_OF_MONTH);
2560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        } else {
2570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            enabledDayRangeEnd = 31;
2580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        v.setMonthParams(selectedDay, month, year, mFirstDayOfWeek,
2610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                enabledDayRangeStart, enabledDayRangeEnd);
2620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
26360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final ViewHolder holder = new ViewHolder(position, itemView, v);
26460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        mItems.put(position, holder);
2650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
26660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        container.addView(itemView);
2670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
26860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        return holder;
2690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
2720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public void destroyItem(ViewGroup container, int position, Object object) {
27360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final ViewHolder holder = (ViewHolder) object;
27460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        container.removeView(holder.container);
2750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        mItems.remove(position);
2770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
2800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public int getItemPosition(Object object) {
28160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final ViewHolder holder = (ViewHolder) object;
28260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        return holder.position;
2830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
2850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    @Override
2860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public CharSequence getPageTitle(int position) {
28760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        final SimpleMonthView v = mItems.get(position).calendar;
2880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        if (v != null) {
289e264f9503b8ffcb2cae84e4e5bb2a03dd0610221Alan Viverette            return v.getMonthYearLabel();
2900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
2910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        return null;
2920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
2930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
294e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount    SimpleMonthView getView(Object object) {
295e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount        if (object == null) {
296e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount            return null;
297e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount        }
298e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount        final ViewHolder holder = (ViewHolder) object;
299e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount        return holder.calendar;
300e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount    }
301e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount
3020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
3030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        @Override
3040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        public void onDayClick(SimpleMonthView view, Calendar day) {
3055c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette            if (day != null) {
3060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                setSelectedDay(day);
3070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
3080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                if (mOnDaySelectedListener != null) {
30978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette                    mOnDaySelectedListener.onDaySelected(DayPickerPagerAdapter.this, day);
3100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette                }
3110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette            }
3120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette        }
3130ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    };
3140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette
31560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    private static class ViewHolder {
31660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        public final int position;
31760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        public final View container;
31860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        public final SimpleMonthView calendar;
31960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
32060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        public ViewHolder(int position, View container, SimpleMonthView calendar) {
32160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            this.position = position;
32260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            this.container = container;
32360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette            this.calendar = calendar;
32460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette        }
32560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette    }
32660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette
3270ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    public interface OnDaySelectedListener {
32878bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette        public void onDaySelected(DayPickerPagerAdapter view, Calendar day);
3290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette    }
3300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette}
331