package moontime.droid; import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.List; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import com.google.inject.internal.Lists; public class CalendarView extends TableLayout implements OnClickListener { private List<DayView> _dayViews = Lists.newArrayList(); private OnDayClickListener _onDayClickListener; private Calendar _currentMonthYearToView; private DayView _selectedDay; public CalendarView(Context context) { super(context); } public CalendarView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray styleAttributes = context.obtainStyledAttributes(attrs, R.styleable.CalendarView); createHeaderRow(context, styleAttributes); createWeekRows(context, styleAttributes, generateLayoutParams(attrs)); } public void setOnDayClickListener(OnDayClickListener onDayClickListener) { _onDayClickListener = onDayClickListener; } public void update(Calendar monthYearToView) { _currentMonthYearToView = monthYearToView; int lastDay = monthYearToView.getActualMaximum(Calendar.DAY_OF_MONTH); int currentMonthDay = 1; for (int i = 0; i < _dayViews.size(); i++) { DayView dayView = _dayViews.get(i); dayView.clear(); if (currentMonthDay == 1 && i + 1 < monthYearToView.get(Calendar.DAY_OF_WEEK)) { // before the month starts } else if (currentMonthDay > lastDay) { // after the month ends } else { dayView.setDay(currentMonthDay); currentMonthDay++; } } } private void createHeaderRow(Context context, TypedArray styleAttributes) { int textSize = styleAttributes.getColor(R.styleable.CalendarView_text_size, 18); int backgroundColor = styleAttributes.getColor(R.styleable.CalendarView_background_header, Color.BLACK); String[] shortWeekdays = new DateFormatSymbols().getShortWeekdays(); TableRow headerRow = createTableRow(context); for (int i = 1; i < shortWeekdays.length; i++) { TextView textView = createHeaderView(context, textSize, backgroundColor); textView.setText(shortWeekdays[i]); headerRow.addView(textView); } addView(headerRow); } public TextView getDayView(int day) { for (int i = day - 1; i < _dayViews.size(); i++) { if (_dayViews.get(i).getDay() == day) { return _dayViews.get(i); } } throw new IllegalArgumentException("no day '" + day + "' found in calendar for " + _currentMonthYearToView); } private void createWeekRows(Context context, TypedArray styleAttributes, LayoutParams layoutParams) { layoutParams.setMargins(3, 3, 3, 3); int backgroundColor = styleAttributes.getColor(R.styleable.CalendarView_background_rows, Color.BLACK); int textSize = styleAttributes.getColor(R.styleable.CalendarView_text_size, 18); System.out.println("CalendarView.createWeekRows()" + textSize); int backgroundSelectedColor = styleAttributes .getColor(R.styleable.CalendarView_background_selectedDay, Color.BLACK); for (int week = 0; week < 6; week++) { TableRow tableRow = createTableRow(context); for (int weekDay = 0; weekDay < 7; weekDay++) { DayView textView = createDayView(context, textSize, backgroundColor, backgroundSelectedColor); tableRow.addView(textView); _dayViews.add(textView); } addView(tableRow); } } private TableRow createTableRow(Context context) { TableRow row = new TableRow(context); row.setGravity(Gravity.CENTER_HORIZONTAL); LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 1, 0, 0); row.setLayoutParams(layoutParams); return row; } private TextView createHeaderView(Context context, int textSize, int backgroundColor) { TextView textView = new TextView(context); textView.setGravity(Gravity.CENTER); textView.setTextSize(textSize); textView.setBackgroundColor(backgroundColor); return textView; } private DayView createDayView(Context context, int textSize, int backgroundColor, int backgroundSelectedColor) { DayView dayView = new DayView(context, backgroundColor, backgroundSelectedColor); dayView.setTextSize(textSize); dayView.setGravity(Gravity.CENTER); dayView.setOnClickListener(this); return dayView; } @Override public void onClick(View v) { DayView dayView = (DayView) v; if (dayView.getDay() < 1) { return; } if (_selectedDay != null) { _selectedDay.deselect(); } _selectedDay = dayView; _selectedDay.select(); if (_onDayClickListener != null) { _onDayClickListener.onClick(dayView, dayView.getDay()); } } public static interface OnDayClickListener { public void onClick(TextView view, int day); } private static class DayView extends TextView { private final int _backgroundDefaultColor; private final int _backgroundSelectedColor; private Drawable _backgroundBeforeSelected;; private int _day; public DayView(Context context, int backgroundColor, int selectedColor) { super(context); _backgroundDefaultColor = backgroundColor; _backgroundSelectedColor = selectedColor; setBackgroundColor(backgroundColor); } public void clear() { setDay(-1); setText(" "); setBackgroundColor(_backgroundDefaultColor); } public int getDay() { return _day; } public void setDay(int day) { _day = day; setText(Integer.toString(day)); } public void select() { _backgroundBeforeSelected = getBackground(); setBackgroundColor(_backgroundSelectedColor); } public void deselect() { setBackgroundDrawable(_backgroundBeforeSelected); _backgroundBeforeSelected = null; } } }