CalendarController类:计算日历的一些常用方法
package com.qingqing.base.view.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
/**
* @author whuthm
*
*/
public class CalendarController {
public static final long ONE_MIN = 60 * 1000;
public static final long ONE_HOUR = 60 * ONE_MIN;
public static final long ONE_DAY = 24 * ONE_HOUR;
public static final long ONE_WEEK = 7 * ONE_DAY;
public static final int MONTH_COUNT_OF_YEAR = 12;
public static final int DAY_COUNT_OF_WEEK = 7;
public static final int WEEK_MAX_COUNT_OF_MONTH = 6;
public static final int MIN_CALENDAR_YEAR = 1970;
public static final int MAX_CALENDAR_YEAR = 2036;
public static final int MIN_CALENDAR_WEEK = 0;
public static final int MAX_CALENDAR_WEEK = 3497; // weeks between 1/1/1970
// and 1/1/2037
public static final int WEEK_COUNT = MAX_CALENDAR_WEEK - MIN_CALENDAR_WEEK;
public static final int MONTH_COUNT = MAX_CALENDAR_YEAR * MONTH_COUNT_OF_YEAR
- MIN_CALENDAR_YEAR * MONTH_COUNT_OF_YEAR;
public static final long START_TIME_MILLIS = getTimeInMillis(MIN_CALENDAR_YEAR, 1, 1);
public static long getTimeInMillis(int year, int month, int day) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, day);
return c.getTimeInMillis();
}
public static long getTimeInMillis(int year, int month, int day, int field, int value) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, day);
c.add(field, value);
return c.getTimeInMillis();
}
/**
* 指定日期为当年第几周
*/
public static int getWeekOfYear(int year, int month, int day) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, day);
return c.get(Calendar.WEEK_OF_YEAR);
}
/**
* 获取指定月份的总天数
*/
public static int getCurrentMonthDays(int month) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.set(Calendar.MONTH, month);
return c.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/**
* 获取指定年份有多少周
*/
public static int getTotalWeekOfYear(int year) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
return c.getActualMaximum(Calendar.WEEK_OF_YEAR);
}
/**
* 判断是否是当前月
*/
public static boolean isCurrentMonth(int year, int month) {
Calendar c = Calendar.getInstance(Locale.getDefault());
return c.get(Calendar.MONTH) == month - 1 && year == c.get(Calendar.YEAR);
}
/**
* 判断是否是今天
*/
public static boolean isToday(int year, int month, int day) {
Calendar c = Calendar.getInstance(Locale.getDefault());
return day == c.get(Calendar.DAY_OF_MONTH) && month == c.get(Calendar.MONTH)
&& year == c.get(Calendar.YEAR);
}
/**
* 计算指定的月份共有多少天
*/
public static int getTotalDaysOfMonth(int year, int month) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
return c.getActualMaximum(Calendar.DAY_OF_MONTH);
}
public static List<Day> getMonthDays(int year, int month) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, 1);
int dayOfFirstWeek = c.get(Calendar.DAY_OF_WEEK);
int daysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
long curMillis = c.getTimeInMillis();
long startMillis = dayOfFirstWeek > Calendar.SUNDAY ? curMillis - ONE_DAY
* (dayOfFirstWeek - 1) : curMillis;
List<Day> days = new ArrayList<Day>();
for (int i = 0; i < DAY_COUNT_OF_WEEK * WEEK_MAX_COUNT_OF_MONTH; i++) {
Day day = new Day(startMillis + i * ONE_DAY);
day.setCurrent(i >= dayOfFirstWeek - 1
&& i < dayOfFirstWeek - 1 + daysOfMonth);
days.add(day);
}
return days;
}
public static List<Day> getMonthDaysByIndex(int index) {
// 1970-1-1为第一个月
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, MIN_CALENDAR_YEAR + index / MONTH_COUNT_OF_YEAR);
c.set(Calendar.MONTH, index % MONTH_COUNT_OF_YEAR);
c.set(Calendar.DAY_OF_MONTH, 1);
int dayOfFirstWeek = c.get(Calendar.DAY_OF_WEEK);
int daysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
long curMillis = c.getTimeInMillis();
long startMillis = dayOfFirstWeek > Calendar.SUNDAY ? curMillis - ONE_DAY
* (dayOfFirstWeek - 1) : curMillis;
List<Day> days = new ArrayList<Day>();
for (int i = 0; i < DAY_COUNT_OF_WEEK * WEEK_MAX_COUNT_OF_MONTH; i++) {
//
Day day = new Day(startMillis + i * ONE_DAY);
// 判断是否在当月
day.setCurrent(i >= dayOfFirstWeek - 1
&& i < dayOfFirstWeek - 1 + daysOfMonth);
days.add(day);
}
return days;
}
public static int getMonthIndex(int year, int month) {
return (year - MIN_CALENDAR_YEAR) * MONTH_COUNT_OF_YEAR + month - 1;
}
public static List<Day> getWeekDays(int year, int month, int dayOfMonth) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
long curMillis = c.getTimeInMillis();
long startMillis = dayOfWeek > Calendar.SUNDAY ? curMillis - ONE_DAY
* (dayOfWeek - 1) : curMillis;
List<Day> days = new ArrayList<Day>();
for (int i = 0; i < DAY_COUNT_OF_WEEK; i++) {
Day day = new Day(startMillis + i * ONE_DAY);
days.add(day);
}
return days;
}
public static List<Day> getWeekDaysByIndex(int index) {
// 1970-1-1为第一周,index=0
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.setTimeInMillis(START_TIME_MILLIS + index * ONE_WEEK);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
long curMillis = c.getTimeInMillis();
long startMillis = dayOfWeek > Calendar.SUNDAY ? curMillis - ONE_DAY
* (dayOfWeek - 1) : curMillis;
List<Day> days = new ArrayList<Day>();
for (int i = 0; i < DAY_COUNT_OF_WEEK; i++) {
Day day = new Day(startMillis + i * ONE_DAY);
days.add(day);
// Log.e("" + index,
// "getWeekDaysByIndex " + day.getYear() + "-" + day.getMonth() +
// "-"
// + day.getDayOfMonth());
}
return days;
}
public static int getWeekIndex(int year, int month, int day) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, day);
int weekOfYear = c.get(Calendar.WEEK_OF_YEAR);
if (weekOfYear == 1 && month == MONTH_COUNT_OF_YEAR) {
return getTotalWeekFromMinYear(year);
}
else {
return getTotalWeekFromMinYear(year - 1) + weekOfYear - 1;
}
}
public static int getTotalWeekFromMinYear(int curYear) {
int totalWeek = 0;
for (int i = MIN_CALENDAR_YEAR; i <= curYear; i++) {
totalWeek += getTotalWeekOfYear(i);
}
return totalWeek;
}
public static Day getDayByIndexAndWeek(int index, int dayOfWeek) {
// 1970-1-1为第一周,index=0
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.setTimeInMillis(START_TIME_MILLIS + index * ONE_WEEK);
int otherDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
long curMillis = c.getTimeInMillis();
long startMillis = otherDayOfWeek > Calendar.SUNDAY ? curMillis - ONE_DAY
* (otherDayOfWeek - 1) : curMillis;
return new Day(startMillis + (dayOfWeek - 1) * ONE_DAY);
}
public static Day getDayByIndexAndMonth(int index, int dayOfMonth) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, MIN_CALENDAR_YEAR + index / MONTH_COUNT_OF_YEAR);
c.set(Calendar.MONTH, index % MONTH_COUNT_OF_YEAR);
int daysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
c.set(Calendar.DAY_OF_MONTH, Math.min(Math.max(1, dayOfMonth), daysOfMonth));
return new Day(c.getTimeInMillis());
}
public static int getKeyByTimeInMillis(long timeMillis) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.setTimeInMillis(timeMillis);
return getKeyByDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1,
c.get(Calendar.DAY_OF_MONTH));
}
public static int getKeyByDate(int year, int month, int day) {
return year * 10000 + month * 100 + day;
}
}
Day类:代表某一天
package com.qingqing.base.view.calendar;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* @author whuthm
*
*/
public class Day {
private int mKey;
private int mYear;
private int mMonth;
private int mDayOfMonth;
private long mMilliSeconds;
private int mDayOfWeek;
private boolean mSelected;
private boolean mCurrent = true;
public Day(Day day) {
setMilliseconds(day.getMilliSeconds());
setCurrent(day.isCurrent());
setSelected(day.isSelected());
}
public Day(long milliseconds) {
setMilliseconds(milliseconds);
}
public Day(Date date) {
setMilliseconds(date.getTime());
}
public Day(int year, int month, int dayOfMonth) {
setDate(year, month, dayOfMonth);
}
public void setMilliseconds(long milliseconds) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.setTimeInMillis(milliseconds);
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH) + 1;
mDayOfMonth = c.get(Calendar.DAY_OF_MONTH);
mDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
mMilliSeconds = milliseconds;
mKey = CalendarController.getKeyByDate(mYear, mMonth, mDayOfMonth);
}
public void setDate(int year, int month, int dayOfMonth) {
Calendar c = Calendar.getInstance(Locale.getDefault());
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
mYear = year;
mMonth = month;
mDayOfMonth = dayOfMonth;
mDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
mMilliSeconds = c.getTimeInMillis();
mKey = CalendarController.getKeyByDate(mYear, mMonth, mDayOfMonth);
}
public boolean isToday() {
return false;
}
public int getYear() {
return mYear;
}
public int getMonth() {
return mMonth;
}
public int getDayOfMonth() {
return mDayOfMonth;
}
public int getDayOfWeek() {
return mDayOfWeek;
}
public long getMilliSeconds() {
return mMilliSeconds;
}
public int getKey() {
return mKey;
}
public void setSelected(boolean selected) {
mSelected = selected;
}
public boolean isSelected() {
return mSelected;
}
public boolean isCurrent() {
return mCurrent;
}
public void setCurrent(boolean current) {
mCurrent = current;
}
public void destory() {
// nothing
}
public static boolean isSameDay(Day day1, Day day2) {
return day1 != null && day2 != null && day1.getYear() == day2.getYear()
&& day1.getMonth() == day2.getMonth()
&& day1.getDayOfMonth() == day2.getDayOfMonth();
}
public static boolean isAfterToday(Day day, Day today) {
return day.getYear() > today.getYear()
|| (day.getYear() == today.getYear() && day.getMonth() > today.getMonth())
|| (day.getYear() == today.getYear()
&& day.getMonth() == today.getMonth() && day.getDayOfMonth() > today
.getDayOfMonth());
}
@Override
public String toString() {
return mYear + "-" + mMonth + "-" + mDayOfMonth;
}
}
DayGridAdpter类;日历适配
package com.qingqing.base.view.calendar;
import java.util.List;
import com.qingqing.base.view.BaseAdapter;
import com.qingqing.qingqingbase.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* @author whuthm
*
*/
public class DayGridAdapter extends BaseAdapter<Day> {
public DayGridAdapter(Context context, List<Day> list) {
super(context, list);
}
@Override
public View createView(Context context, ViewGroup parent) {
return new DayView(context);
}
@Override
public BaseAdapter.ViewHolder<Day> createViewHolder() {
return new DayViewHolder();
}
public static class DayViewHolder extends BaseAdapter.ViewHolder<Day> {
DayView dayView;
@Override
public void init(Context context, View convertView) {
if (convertView instanceof DayView) {
dayView = (DayView) convertView;
}
}
@Override
public void update(Context context, Day data) {
if (dayView != null) {
dayView.update(data);
}
}
}
}
DayView;网格view,代表某一天的view的实现
package com.qingqing.base.view.calendar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* @author whuthm
* @date 2015-7-28
*/
public class DayView extends RelativeLayout {
protected Day mDay;
public DayView(Context context) {
this(context, null);
}
public DayView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DayView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
@Override
public void setSelected(boolean selected) {
super.setSelected(selected);
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
}
public void update(Day day) {
if (day != null) {
mDay = day;
Drawable bg = getBackground();
if (bg != null) {
bg.setLevel(day.isSelected() ? 1 : 0);
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mDay != null) {
mDay.destory();
}
mDay = null;
}
}
DayPagerAdapter:滑动时,每一页的适配器(月或者周)
package com.qingqing.base.view.calendar;
import java.util.List;
import com.qingqing.qingqingbase.R;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
/**
* @author whuthm
*
*/
public abstract class DayPagerAdapter extends PagerAdapter {
private SparseArray<GridView> mGridViews = new SparseArray<GridView>();
protected Context mContext;
public DayPagerAdapter(Context context) {
mContext = context;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
int count = getCount();
if (position >= 0 && position < count) {
GridView gridView = createGridView(container, position);
gridView.setAdapter(createGridAdapter(mContext, createDays(position)));
gridView.setTag(position);
container.addView(gridView);
mGridViews.put(position, gridView);
return gridView;
}
return super.instantiateItem(container, position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (object instanceof View) {
View child = (View) object;
if (container.indexOfChild(child) >= 0) {
container.removeView(child);
child.setTag(null);
mGridViews.remove(position);
}
}
}
@Override
public int getItemPosition(Object object) {
if (!(object instanceof View)) {
return POSITION_NONE;
}
View child = (View) object;
Object tag = child.getTag();
int index = POSITION_NONE;
if ((tag instanceof Integer)) {
index = (Integer) tag;
}
return index;
}
public GridView getGridViewByPos(int pos) {
return mGridViews.get(pos);
}
public GridView createGridView(ViewGroup container, int position) {
return new GridView(container.getContext());
}
public DayGridAdapter createGridAdapter(Context context, List<Day> days) {
return new DayGridAdapter(context, days);
}
public abstract List<Day> createDays(int position);
}
MonthPagerAdapter:日历的月适配器
package com.qingqing.base.view.calendar;
import java.util.List;
import android.content.Context;
/**
* @author whuthm
*
*/
public class MonthPagerAdapter extends DayPagerAdapter {
public MonthPagerAdapter(Context context) {
super(context);
}
@Override
public int getCount() {
return CalendarController.MONTH_COUNT;
}
@Override
public List<Day> createDays(int positon) {
return CalendarController.getMonthDaysByIndex(positon);
}
}
WeekPagerAdapter:日历的周适配器
package com.qingqing.base.view.calendar;
import java.util.List;
import android.content.Context;
/**
* @author whuthm
*
*/
public class WeekPagerAdapter extends DayPagerAdapter {
public WeekPagerAdapter(Context context) {
super(context);
}
@Override
public int getCount() {
return CalendarController.WEEK_COUNT;
}
@Override
public List<Day> createDays(int position) {
return CalendarController.getWeekDaysByIndex(position);
}
}