1/* 2 * Copyright (C) 2013 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 com.android.datetimepicker.date; 18 19import android.annotation.SuppressLint; 20import android.content.Context; 21import android.text.format.Time; 22import android.util.Log; 23import android.view.View; 24import android.view.ViewGroup; 25import android.widget.AbsListView.LayoutParams; 26import android.widget.BaseAdapter; 27 28import com.android.datetimepicker.date.SimpleMonthView.OnDayClickListener; 29 30import java.util.Calendar; 31import java.util.HashMap; 32 33/** 34 * An adapter for a list of {@link SimpleMonthView} items. 35 */ 36public class SimpleMonthAdapter extends BaseAdapter implements OnDayClickListener { 37 38 private static final String TAG = "SimpleMonthAdapter"; 39 40 private final Context mContext; 41 private final DatePickerController mController; 42 43 private CalendarDay mSelectedDay; 44 45 protected static int WEEK_7_OVERHANG_HEIGHT = 7; 46 protected static final int MONTHS_IN_YEAR = 12; 47 48 /** 49 * A convenience class to represent a specific date. 50 */ 51 public static class CalendarDay { 52 private Calendar calendar; 53 private Time time; 54 int year; 55 int month; 56 int day; 57 58 public CalendarDay() { 59 setTime(System.currentTimeMillis()); 60 } 61 62 public CalendarDay(long timeInMillis) { 63 setTime(timeInMillis); 64 } 65 66 public CalendarDay(Calendar calendar) { 67 year = calendar.get(Calendar.YEAR); 68 month = calendar.get(Calendar.MONTH); 69 day = calendar.get(Calendar.DAY_OF_MONTH); 70 } 71 72 public CalendarDay(int year, int month, int day) { 73 setDay(year, month, day); 74 } 75 76 public void set(CalendarDay date) { 77 year = date.year; 78 month = date.month; 79 day = date.day; 80 } 81 82 public void setDay(int year, int month, int day) { 83 this.year = year; 84 this.month = month; 85 this.day = day; 86 } 87 88 public void setJulianDay(int julianDay) { 89 if (time == null) { 90 time = new Time(); 91 } 92 time.setJulianDay(julianDay); 93 setTime(time.toMillis(false)); 94 } 95 96 private void setTime(long timeInMillis) { 97 if (calendar == null) { 98 calendar = Calendar.getInstance(); 99 } 100 calendar.setTimeInMillis(timeInMillis); 101 month = calendar.get(Calendar.MONTH); 102 year = calendar.get(Calendar.YEAR); 103 day = calendar.get(Calendar.DAY_OF_MONTH); 104 } 105 } 106 107 public SimpleMonthAdapter(Context context, 108 DatePickerController controller) { 109 mContext = context; 110 mController = controller; 111 init(); 112 setSelectedDay(mController.getSelectedDay()); 113 } 114 115 /** 116 * Updates the selected day and related parameters. 117 * 118 * @param day The day to highlight 119 */ 120 public void setSelectedDay(CalendarDay day) { 121 mSelectedDay = day; 122 notifyDataSetChanged(); 123 } 124 125 public CalendarDay getSelectedDay() { 126 return mSelectedDay; 127 } 128 129 /** 130 * Set up the gesture detector and selected time 131 */ 132 protected void init() { 133 mSelectedDay = new CalendarDay(System.currentTimeMillis()); 134 } 135 136 @Override 137 public int getCount() { 138 return ((mController.getMaxYear() - mController.getMinYear()) + 1) * MONTHS_IN_YEAR; 139 } 140 141 @Override 142 public Object getItem(int position) { 143 return null; 144 } 145 146 @Override 147 public long getItemId(int position) { 148 return position; 149 } 150 151 @Override 152 public boolean hasStableIds() { 153 return true; 154 } 155 156 @SuppressLint("NewApi") 157 @SuppressWarnings("unchecked") 158 @Override 159 public View getView(int position, View convertView, ViewGroup parent) { 160 SimpleMonthView v; 161 HashMap<String, Integer> drawingParams = null; 162 if (convertView != null) { 163 v = (SimpleMonthView) convertView; 164 // We store the drawing parameters in the view so it can be recycled 165 drawingParams = (HashMap<String, Integer>) v.getTag(); 166 } else { 167 v = new SimpleMonthView(mContext); 168 // Set up the new view 169 LayoutParams params = new LayoutParams( 170 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 171 v.setLayoutParams(params); 172 v.setClickable(true); 173 v.setOnDayClickListener(this); 174 } 175 if (drawingParams == null) { 176 drawingParams = new HashMap<String, Integer>(); 177 } 178 drawingParams.clear(); 179 180 final int month = position % MONTHS_IN_YEAR; 181 final int year = position / MONTHS_IN_YEAR + mController.getMinYear(); 182 Log.d(TAG, "Year: " + year + ", Month: " + month); 183 184 int selectedDay = -1; 185 if (isSelectedDayInMonth(year, month)) { 186 selectedDay = mSelectedDay.day; 187 } 188 189 // Invokes requestLayout() to ensure that the recycled view is set with the appropriate 190 // height/number of weeks before being displayed. 191 v.reuse(); 192 193 drawingParams.put(SimpleMonthView.VIEW_PARAMS_SELECTED_DAY, selectedDay); 194 drawingParams.put(SimpleMonthView.VIEW_PARAMS_YEAR, year); 195 drawingParams.put(SimpleMonthView.VIEW_PARAMS_MONTH, month); 196 drawingParams.put(SimpleMonthView.VIEW_PARAMS_WEEK_START, mController.getFirstDayOfWeek()); 197 v.setMonthParams(drawingParams); 198 v.invalidate(); 199 return v; 200 } 201 202 private boolean isSelectedDayInMonth(int year, int month) { 203 return mSelectedDay.year == year && mSelectedDay.month == month; 204 } 205 206 207 @Override 208 public void onDayClick(SimpleMonthView view, CalendarDay day) { 209 if (day != null) { 210 onDayTapped(day); 211 } 212 } 213 214 /** 215 * Maintains the same hour/min/sec but moves the day to the tapped day. 216 * 217 * @param day The day that was tapped 218 */ 219 protected void onDayTapped(CalendarDay day) { 220 mController.tryVibrate(); 221 mController.onDayOfMonthSelected(day.year, day.month, day.day); 222 setSelectedDay(day); 223 } 224} 225