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 1960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.IdRes; 2060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.LayoutRes; 2160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.NonNull; 2260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.annotation.Nullable; 230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.Context; 240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.res.ColorStateList; 250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.content.res.TypedArray; 2699441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport android.graphics.Rect; 2768763be41cffbcb4883a0a6293fc1aa9e17a3957Alan Viveretteimport android.icu.util.Calendar; 280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.util.SparseArray; 2960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viveretteimport android.view.LayoutInflater; 300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.View; 310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.view.ViewGroup; 320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viveretteimport android.widget.SimpleMonthView.OnDayClickListener; 330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 3499441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.widget.PagerAdapter; 3599441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas 360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette/** 370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * An adapter for a list of {@link android.widget.SimpleMonthView} items. 380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 3978bf1d329a4c0210394f846be1fd1390314aefc0Alan Viveretteclass DayPickerPagerAdapter extends PagerAdapter { 400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private static final int MONTHS_IN_YEAR = 12; 410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final Calendar mMinDate = Calendar.getInstance(); 430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final Calendar mMaxDate = Calendar.getInstance(); 440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 4560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private final SparseArray<ViewHolder> mItems = new SparseArray<>(); 460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 4760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private final LayoutInflater mInflater; 4860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private final int mLayoutResId; 4960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private final int mCalendarViewId; 5060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 5160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private Calendar mSelectedDay = null; 520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int mMonthTextAppearance; 540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int mDayOfWeekTextAppearance; 550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int mDayTextAppearance; 560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ColorStateList mCalendarTextColor; 580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ColorStateList mDaySelectorColor; 590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private ColorStateList mDayHighlightColor; 600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private OnDaySelectedListener mOnDaySelectedListener; 620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 6360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private int mCount; 640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int mFirstDayOfWeek; 650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 6678bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public DayPickerPagerAdapter(@NonNull Context context, @LayoutRes int layoutResId, 6760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette @IdRes int calendarViewId) { 6860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette mInflater = LayoutInflater.from(context); 6960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette mLayoutResId = layoutResId; 7060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette mCalendarViewId = calendarViewId; 7160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final TypedArray ta = context.obtainStyledAttributes(new int[] { 730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette com.android.internal.R.attr.colorControlHighlight}); 740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayHighlightColor = ta.getColorStateList(0); 750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette ta.recycle(); 760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 7860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public void setRange(@NonNull Calendar min, @NonNull Calendar max) { 790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mMinDate.setTimeInMillis(min.getTimeInMillis()); 800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mMaxDate.setTimeInMillis(max.getTimeInMillis()); 810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 8260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR); 8360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final int diffMonth = mMaxDate.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH); 8460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette mCount = diffMonth + MONTHS_IN_YEAR * diffYear + 1; 8560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 860ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Positions are now invalid, clear everything and start over. 870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette notifyDataSetChanged(); 880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Sets the first day of the week. 920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param weekStart which day the week should start on, valid values are 940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY} 950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void setFirstDayOfWeek(int weekStart) { 970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mFirstDayOfWeek = weekStart; 980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Update displayed views. 1000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int count = mItems.size(); 1010ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette for (int i = 0; i < count; i++) { 10260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final SimpleMonthView monthView = mItems.valueAt(i).calendar; 1030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette monthView.setFirstDayOfWeek(weekStart); 1040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public int getFirstDayOfWeek() { 1080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mFirstDayOfWeek; 1090ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1100ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 111698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov public boolean getBoundsForDate(Calendar day, Rect outBounds) { 112698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov final int position = getPositionForDay(day); 113698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov final ViewHolder monthView = mItems.get(position, null); 114698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov if (monthView == null) { 115698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov return false; 116698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov } else { 117698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH); 118698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov return monthView.calendar.getBoundsForDay(dayOfMonth, outBounds); 119698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov } 120698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov } 121698b751dc78f8a325c5b513cacd3335151f807eaKirill Grouchnikov 1220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 1230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Sets the selected day. 1240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 1250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param day the selected day 1260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 12760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public void setSelectedDay(@Nullable Calendar day) { 1280ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int oldPosition = getPositionForDay(mSelectedDay); 1290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int newPosition = getPositionForDay(day); 1300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Clear the old position if necessary. 13260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette if (oldPosition != newPosition && oldPosition >= 0) { 13360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder oldMonthView = mItems.get(oldPosition, null); 1340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (oldMonthView != null) { 13560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette oldMonthView.calendar.setSelectedDay(-1); 1360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette // Set the new position. 14060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette if (newPosition >= 0) { 14160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder newMonthView = mItems.get(newPosition, null); 14260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette if (newMonthView != null) { 14360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH); 14460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette newMonthView.calendar.setSelectedDay(dayOfMonth); 14560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette } 1460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mSelectedDay = day; 1490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 1520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Sets the listener to call when the user selects a day. 1530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 1540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param listener The listener to call. 1550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 1560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void setOnDaySelectedListener(OnDaySelectedListener listener) { 1570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mOnDaySelectedListener = listener; 1580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette void setCalendarTextColor(ColorStateList calendarTextColor) { 1610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mCalendarTextColor = calendarTextColor; 162d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette notifyDataSetChanged(); 1630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette void setDaySelectorColor(ColorStateList selectorColor) { 1660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDaySelectorColor = selectorColor; 167d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette notifyDataSetChanged(); 1680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette void setMonthTextAppearance(int resId) { 1710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mMonthTextAppearance = resId; 172d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette notifyDataSetChanged(); 1730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1750ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette void setDayOfWeekTextAppearance(int resId) { 1760ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayOfWeekTextAppearance = resId; 177d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette notifyDataSetChanged(); 1780ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1800ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette int getDayOfWeekTextAppearance() { 1810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mDayOfWeekTextAppearance; 1820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette void setDayTextAppearance(int resId) { 1850ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mDayTextAppearance = resId; 186d6d9a94f80f3469d5a1774c4d28ca57223fe1e61Alan Viverette notifyDataSetChanged(); 1870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette int getDayTextAppearance() { 1900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return mDayTextAppearance; 1910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1930ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 1940ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public int getCount() { 19560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette return mCount; 1960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 1970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 1980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 1990ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public boolean isViewFromObject(View view, Object object) { 20060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder holder = (ViewHolder) object; 20160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette return view == holder.container; 2020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int getMonthForPosition(int position) { 205bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette return (position + mMinDate.get(Calendar.MONTH)) % MONTHS_IN_YEAR; 2060ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2070ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2080ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private int getYearForPosition(int position) { 209bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette final int yearOffset = (position + mMinDate.get(Calendar.MONTH)) / MONTHS_IN_YEAR; 210bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette return yearOffset + mMinDate.get(Calendar.YEAR); 2110ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2120ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 21360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private int getPositionForDay(@Nullable Calendar day) { 21460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette if (day == null) { 21560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette return -1; 21660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette } 21760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 218bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette final int yearOffset = day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR); 219bd51b4d0b930f8c64920954f4f9e5033e0001d5eAlan Viverette final int monthOffset = day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH); 22078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette final int position = yearOffset * MONTHS_IN_YEAR + monthOffset; 22178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette return position; 2220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public Object instantiateItem(ViewGroup container, int position) { 22660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final View itemView = mInflater.inflate(mLayoutResId, container, false); 22760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 2288e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette final SimpleMonthView v = itemView.findViewById(mCalendarViewId); 2290ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setOnDayClickListener(mOnDayClickListener); 2300ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setMonthTextAppearance(mMonthTextAppearance); 2310ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance); 2320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDayTextAppearance(mDayTextAppearance); 2330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mDaySelectorColor != null) { 2350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDaySelectorColor(mDaySelectorColor); 2360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mDayHighlightColor != null) { 2390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDayHighlightColor(mDayHighlightColor); 2400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mCalendarTextColor != null) { 2430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setMonthTextColor(mCalendarTextColor); 2440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDayOfWeekTextColor(mCalendarTextColor); 2450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setDayTextColor(mCalendarTextColor); 2460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int month = getMonthForPosition(position); 2490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int year = getYearForPosition(position); 2500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int selectedDay; 25260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette if (mSelectedDay != null && mSelectedDay.get(Calendar.MONTH) == month) { 2530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH); 2540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } else { 2550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette selectedDay = -1; 2560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int enabledDayRangeStart; 2590ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mMinDate.get(Calendar.MONTH) == month && mMinDate.get(Calendar.YEAR) == year) { 2600ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette enabledDayRangeStart = mMinDate.get(Calendar.DAY_OF_MONTH); 2610ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } else { 2620ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette enabledDayRangeStart = 1; 2630ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2640ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2650ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int enabledDayRangeEnd; 2660ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mMaxDate.get(Calendar.MONTH) == month && mMaxDate.get(Calendar.YEAR) == year) { 2670ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette enabledDayRangeEnd = mMaxDate.get(Calendar.DAY_OF_MONTH); 2680ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } else { 2690ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette enabledDayRangeEnd = 31; 2700ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2710ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2720ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette v.setMonthParams(selectedDay, month, year, mFirstDayOfWeek, 2730ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette enabledDayRangeStart, enabledDayRangeEnd); 2740ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 27560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder holder = new ViewHolder(position, itemView, v); 27660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette mItems.put(position, holder); 2770ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 27860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette container.addView(itemView); 2790ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 28060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette return holder; 2810ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2820ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2830ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2840ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void destroyItem(ViewGroup container, int position, Object object) { 28560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder holder = (ViewHolder) object; 28660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette container.removeView(holder.container); 2870ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2880ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette mItems.remove(position); 2890ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2900ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2910ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2920ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public int getItemPosition(Object object) { 29360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final ViewHolder holder = (ViewHolder) object; 29460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette return holder.position; 2950ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 2960ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 2970ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 2980ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public CharSequence getPageTitle(int position) { 29960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette final SimpleMonthView v = mItems.get(position).calendar; 3000ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (v != null) { 301e264f9503b8ffcb2cae84e4e5bb2a03dd0610221Alan Viverette return v.getMonthYearLabel(); 3020ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3030ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return null; 3040ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3050ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 306e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount SimpleMonthView getView(Object object) { 307e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount if (object == null) { 308e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount return null; 309e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount } 310e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount final ViewHolder holder = (ViewHolder) object; 311e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount return holder.calendar; 312e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount } 313e998c3f5f6e7ac21b18cd449088ac2b76b65671fGeorge Mount 3140ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() { 3150ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette @Override 3160ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public void onDayClick(SimpleMonthView view, Calendar day) { 3175c33949d0272c4dfc313cf8b56d28597e2ec2c62Alan Viverette if (day != null) { 3180ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette setSelectedDay(day); 3190ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 3200ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (mOnDaySelectedListener != null) { 32178bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette mOnDaySelectedListener.onDaySelected(DayPickerPagerAdapter.this, day); 3220ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3230ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3240ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3250ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette }; 3260ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 32760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette private static class ViewHolder { 32860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public final int position; 32960b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public final View container; 33060b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public final SimpleMonthView calendar; 33160b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 33260b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette public ViewHolder(int position, View container, SimpleMonthView calendar) { 33360b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette this.position = position; 33460b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette this.container = container; 33560b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette this.calendar = calendar; 33660b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette } 33760b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette } 33860b674e07bf7346a673abd4a5f40bddeca16e7ffAlan Viverette 3390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public interface OnDaySelectedListener { 34078bf1d329a4c0210394f846be1fd1390314aefc0Alan Viverette public void onDaySelected(DayPickerPagerAdapter view, Calendar day); 3410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 3420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette} 343