| /* |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.datetimepicker.date; |
| |
| import android.annotation.SuppressLint; |
| import android.content.Context; |
| import android.text.format.Time; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.AbsListView.LayoutParams; |
| import android.widget.BaseAdapter; |
| |
| import com.android.datetimepicker.date.MonthView.OnDayClickListener; |
| |
| import java.util.Calendar; |
| import java.util.HashMap; |
| |
| /** |
| * An adapter for a list of {@link MonthView} items. |
| */ |
| abstract class MonthAdapter extends BaseAdapter implements OnDayClickListener { |
| |
| private static final String TAG = "SimpleMonthAdapter"; |
| |
| private final Context mContext; |
| protected final DatePickerController mController; |
| |
| private CalendarDay mSelectedDay; |
| |
| protected static int WEEK_7_OVERHANG_HEIGHT = 7; |
| protected static final int MONTHS_IN_YEAR = 12; |
| |
| /** |
| * A convenience class to represent a specific date. |
| */ |
| public static class CalendarDay { |
| private Calendar calendar; |
| private Time time; |
| int year; |
| int month; |
| int day; |
| |
| public CalendarDay() { |
| setTime(System.currentTimeMillis()); |
| } |
| |
| public CalendarDay(long timeInMillis) { |
| setTime(timeInMillis); |
| } |
| |
| public CalendarDay(Calendar calendar) { |
| year = calendar.get(Calendar.YEAR); |
| month = calendar.get(Calendar.MONTH); |
| day = calendar.get(Calendar.DAY_OF_MONTH); |
| } |
| |
| public CalendarDay(int year, int month, int day) { |
| setDay(year, month, day); |
| } |
| |
| public void set(CalendarDay date) { |
| year = date.year; |
| month = date.month; |
| day = date.day; |
| } |
| |
| public void setDay(int year, int month, int day) { |
| this.year = year; |
| this.month = month; |
| this.day = day; |
| } |
| |
| public synchronized void setJulianDay(int julianDay) { |
| if (time == null) { |
| time = new Time(); |
| } |
| time.setJulianDay(julianDay); |
| setTime(time.toMillis(false)); |
| } |
| |
| private void setTime(long timeInMillis) { |
| if (calendar == null) { |
| calendar = Calendar.getInstance(); |
| } |
| calendar.setTimeInMillis(timeInMillis); |
| month = calendar.get(Calendar.MONTH); |
| year = calendar.get(Calendar.YEAR); |
| day = calendar.get(Calendar.DAY_OF_MONTH); |
| } |
| |
| public int getYear() { |
| return year; |
| } |
| |
| public int getMonth() { |
| return month; |
| } |
| |
| public int getDay() { |
| return day; |
| } |
| } |
| |
| public MonthAdapter(Context context, |
| DatePickerController controller) { |
| mContext = context; |
| mController = controller; |
| init(); |
| setSelectedDay(mController.getSelectedDay()); |
| } |
| |
| /** |
| * Updates the selected day and related parameters. |
| * |
| * @param day The day to highlight |
| */ |
| public void setSelectedDay(CalendarDay day) { |
| mSelectedDay = day; |
| notifyDataSetChanged(); |
| } |
| |
| public CalendarDay getSelectedDay() { |
| return mSelectedDay; |
| } |
| |
| /** |
| * Set up the gesture detector and selected time |
| */ |
| protected void init() { |
| mSelectedDay = new CalendarDay(System.currentTimeMillis()); |
| } |
| |
| @Override |
| public int getCount() { |
| return ((mController.getMaxYear() - mController.getMinYear()) + 1) * MONTHS_IN_YEAR; |
| } |
| |
| @Override |
| public Object getItem(int position) { |
| return null; |
| } |
| |
| @Override |
| public long getItemId(int position) { |
| return position; |
| } |
| |
| @Override |
| public boolean hasStableIds() { |
| return true; |
| } |
| |
| @SuppressLint("NewApi") |
| @SuppressWarnings("unchecked") |
| @Override |
| public View getView(int position, View convertView, ViewGroup parent) { |
| MonthView v; |
| HashMap<String, Integer> drawingParams = null; |
| if (convertView != null) { |
| v = (MonthView) convertView; |
| // We store the drawing parameters in the view so it can be recycled |
| drawingParams = (HashMap<String, Integer>) v.getTag(); |
| } else { |
| v = createMonthView(mContext); |
| // Set up the new view |
| LayoutParams params = new LayoutParams( |
| LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); |
| v.setLayoutParams(params); |
| v.setClickable(true); |
| v.setOnDayClickListener(this); |
| } |
| if (drawingParams == null) { |
| drawingParams = new HashMap<String, Integer>(); |
| } |
| drawingParams.clear(); |
| |
| final int month = position % MONTHS_IN_YEAR; |
| final int year = position / MONTHS_IN_YEAR + mController.getMinYear(); |
| |
| int selectedDay = -1; |
| if (isSelectedDayInMonth(year, month)) { |
| selectedDay = mSelectedDay.day; |
| } |
| |
| // Invokes requestLayout() to ensure that the recycled view is set with the appropriate |
| // height/number of weeks before being displayed. |
| v.reuse(); |
| |
| drawingParams.put(MonthView.VIEW_PARAMS_SELECTED_DAY, selectedDay); |
| drawingParams.put(MonthView.VIEW_PARAMS_YEAR, year); |
| drawingParams.put(MonthView.VIEW_PARAMS_MONTH, month); |
| drawingParams.put(MonthView.VIEW_PARAMS_WEEK_START, mController.getFirstDayOfWeek()); |
| v.setMonthParams(drawingParams); |
| v.invalidate(); |
| return v; |
| } |
| |
| public abstract MonthView createMonthView(Context context); |
| |
| private boolean isSelectedDayInMonth(int year, int month) { |
| return mSelectedDay.year == year && mSelectedDay.month == month; |
| } |
| |
| |
| @Override |
| public void onDayClick(MonthView view, CalendarDay day) { |
| if (day != null) { |
| onDayTapped(day); |
| } |
| } |
| |
| /** |
| * Maintains the same hour/min/sec but moves the day to the tapped day. |
| * |
| * @param day The day that was tapped |
| */ |
| protected void onDayTapped(CalendarDay day) { |
| mController.tryVibrate(); |
| mController.onDayOfMonthSelected(day.year, day.month, day.day); |
| setSelectedDay(day); |
| } |
| } |