1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.widget; 18 19import android.content.Context; 20import android.content.res.ColorStateList; 21import android.view.View; 22import android.view.ViewGroup; 23 24import java.util.Calendar; 25import java.util.HashMap; 26 27/** 28 * An adapter for a list of {@link android.widget.SimpleMonthView} items. 29 */ 30class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayClickListener { 31 private static final String TAG = "SimpleMonthAdapter"; 32 33 private final Context mContext; 34 private final DatePickerController mController; 35 private Calendar mSelectedDay; 36 37 private ColorStateList mCalendarTextColors; 38 39 public SimpleMonthAdapter(Context context, DatePickerController controller) { 40 mContext = context; 41 mController = controller; 42 init(); 43 setSelectedDay(mController.getSelectedDay()); 44 } 45 46 /** 47 * Updates the selected day and related parameters. 48 * 49 * @param day The day to highlight 50 */ 51 public void setSelectedDay(Calendar day) { 52 if (mSelectedDay != day) { 53 mSelectedDay = day; 54 notifyDataSetChanged(); 55 } 56 } 57 58 void setCalendarTextColor(ColorStateList colors) { 59 mCalendarTextColors = colors; 60 } 61 62 /** 63 * Set up the gesture detector and selected time 64 */ 65 protected void init() { 66 mSelectedDay = Calendar.getInstance(); 67 } 68 69 @Override 70 public int getCount() { 71 final int diffYear = mController.getMaxYear() - mController.getMinYear(); 72 final int diffMonth = 1 + mController.getMaxMonth() - mController.getMinMonth() 73 + 12 * diffYear; 74 return diffMonth; 75 } 76 77 @Override 78 public Object getItem(int position) { 79 return null; 80 } 81 82 @Override 83 public long getItemId(int position) { 84 return position; 85 } 86 87 @Override 88 public boolean hasStableIds() { 89 return true; 90 } 91 92 @SuppressWarnings("unchecked") 93 @Override 94 public View getView(int position, View convertView, ViewGroup parent) { 95 SimpleMonthView v; 96 HashMap<String, Integer> drawingParams = null; 97 if (convertView != null) { 98 v = (SimpleMonthView) convertView; 99 // We store the drawing parameters in the view so it can be recycled 100 drawingParams = (HashMap<String, Integer>) v.getTag(); 101 } else { 102 v = new SimpleMonthView(mContext); 103 // Set up the new view 104 AbsListView.LayoutParams params = new AbsListView.LayoutParams( 105 AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT); 106 v.setLayoutParams(params); 107 v.setClickable(true); 108 v.setOnDayClickListener(this); 109 if (mCalendarTextColors != null) { 110 v.setTextColor(mCalendarTextColors); 111 } 112 } 113 if (drawingParams == null) { 114 drawingParams = new HashMap<String, Integer>(); 115 } else { 116 drawingParams.clear(); 117 } 118 final int currentMonth = position + mController.getMinMonth(); 119 final int month = currentMonth % 12; 120 final int year = currentMonth / 12 + mController.getMinYear(); 121 122 int selectedDay = -1; 123 if (isSelectedDayInMonth(year, month)) { 124 selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH); 125 } 126 127 // Invokes requestLayout() to ensure that the recycled view is set with the appropriate 128 // height/number of weeks before being displayed. 129 v.reuse(); 130 131 final int enabledDayRangeStart; 132 if (mController.getMinMonth() == month && mController.getMinYear() == year) { 133 enabledDayRangeStart = mController.getMinDay(); 134 } else { 135 enabledDayRangeStart = 1; 136 } 137 138 final int enabledDayRangeEnd; 139 if (mController.getMaxMonth() == month && mController.getMaxYear() == year) { 140 enabledDayRangeEnd = mController.getMaxDay(); 141 } else { 142 enabledDayRangeEnd = 31; 143 } 144 145 v.setMonthParams(selectedDay, month, year, mController.getFirstDayOfWeek(), 146 enabledDayRangeStart, enabledDayRangeEnd); 147 v.invalidate(); 148 149 return v; 150 } 151 152 private boolean isSelectedDayInMonth(int year, int month) { 153 return mSelectedDay.get(Calendar.YEAR) == year && mSelectedDay.get(Calendar.MONTH) == month; 154 } 155 156 @Override 157 public void onDayClick(SimpleMonthView view, Calendar day) { 158 if (day != null) { 159 onDayTapped(day); 160 } 161 } 162 163 /** 164 * Maintains the same hour/min/sec but moves the day to the tapped day. 165 * 166 * @param day The day that was tapped 167 */ 168 protected void onDayTapped(Calendar day) { 169 mController.tryVibrate(); 170 mController.onDayOfMonthSelected(day.get(Calendar.YEAR), day.get(Calendar.MONTH), 171 day.get(Calendar.DAY_OF_MONTH)); 172 setSelectedDay(day); 173 } 174} 175