/*
* Copyright (C) 2012 www.amsoft.cn
*
* 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.ab.view.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Display;
import android.view.WindowManager;
import android.widget.LinearLayout;
// TODO: Auto-generated Javadoc
/**
* © 2012 amsoft.cn
* 名称:CalendarView.java
* 描述:日历View
*
* @author 还如一梦中
* @version v1.0
* @date:2013-8-23 下午2:03:29
*/
public class CalendarView extends LinearLayout {
/** The tag. */
private String TAG = "CalendarView";
/** The context. */
private Context context;
/** The layout params fw. */
private LinearLayout.LayoutParams layoutParamsFW = null;
/** The m linear layout header. */
private LinearLayout mLinearLayoutHeader = null;
/** The m linear layout content. */
private LinearLayout mLinearLayoutContent = null;
/** The m calendar header. */
private CalendarHeader mCalendarHeader = null;
/** The width. */
private int width = 320;
/** The height. */
private int height = 480;
/** 星期头的行高. */
private int headerHeight = 45;
//行高
/** The row height. */
private int rowHeight = 40;
//每个单元格的宽度
/** The cell width. */
private int cellWidth = 40;
// 日期变量
/** The cal start date. */
public static Calendar calStartDate = Calendar.getInstance();
/** The cal today. */
private Calendar calToday = Calendar.getInstance();
/** The cal selected. */
private Calendar calSelected = null;
//累计日期
/** The cal calendar. */
private Calendar calCalendar = Calendar.getInstance();
/** The current month. */
private int currentMonth = 0;
/** The current year. */
private int currentYear = 0;
//本日历的第一个单元格的星期
/** The first day of week. */
private int firstDayOfWeek = Calendar.SUNDAY;
//当前显示的单元格
/** The m calendar cells. */
private ArrayList<CalendarCell> mCalendarCells = new ArrayList<CalendarCell>();
/** The m on item click listener. */
private AbOnItemClickListener mOnItemClickListener;
/**
* Instantiates a new ab grid view.
*
* @param context the context
*/
public CalendarView(Context context) {
this(context, null);
}
/**
* Instantiates a new calendar view.
*
* @param context the context
* @param attrs the attrs
*/
public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
layoutParamsFW = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
this.setOrientation(LinearLayout.VERTICAL);
this.setBackgroundColor(Color.rgb(255, 255, 255));
WindowManager wManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = wManager.getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
mLinearLayoutHeader = new LinearLayout(context);
mLinearLayoutHeader.setLayoutParams(new LayoutParams(width,headerHeight));
mLinearLayoutHeader.setOrientation(LinearLayout.VERTICAL);
mCalendarHeader = new CalendarHeader(context);
mCalendarHeader.setLayoutParams(new LayoutParams(width,headerHeight));
mLinearLayoutHeader.addView(mCalendarHeader,new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
addView(mLinearLayoutHeader);
mLinearLayoutContent = new LinearLayout(context);
mLinearLayoutContent.setOrientation(LinearLayout.VERTICAL);
addView(mLinearLayoutContent);
cellWidth = (width-20)/7;
rowHeight = cellWidth;
//初始化选中今天
calSelected = Calendar.getInstance();
initRow();
initStartDateForMonth();
initCalendar();
}
/**
* Inits the row.
*/
public void initRow(){
mLinearLayoutContent.removeAllViews();
mCalendarCells.clear();
for (int iRow = 0; iRow < 6; iRow++) {
LinearLayout mLinearLayoutRow = new LinearLayout(context);
mLinearLayoutRow.setLayoutParams(new LayoutParams(width,rowHeight));
mLinearLayoutRow.setOrientation(LinearLayout.HORIZONTAL);
for (int iDay = 0; iDay < 7; iDay++) {
CalendarCell dayCell = new CalendarCell(context,(iRow*7)+iDay,cellWidth,rowHeight);
dayCell.setOnItemClickListener(mOnDayCellClick);
mLinearLayoutRow.addView(dayCell);
mCalendarCells.add(dayCell);
}
mLinearLayoutContent.addView(mLinearLayoutRow);
}
}
/**
* 描述:由于日历上的日期都是从周日开始的,计算第一个单元格的日期.
*/
private void initStartDateForMonth() {
calStartDate.setTimeInMillis(calSelected.getTimeInMillis());
//获取当前的
currentMonth = calStartDate.get(Calendar.MONTH);
currentYear = calStartDate.get(Calendar.YEAR);
calStartDate.set(Calendar.DAY_OF_MONTH, 1);
calStartDate.set(Calendar.HOUR_OF_DAY, 0);
calStartDate.set(Calendar.MINUTE, 0);
calStartDate.set(Calendar.SECOND, 0);
int iDay = 0;
int iStartDay = firstDayOfWeek;
if (iStartDay == Calendar.MONDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
if (iDay < 0)
iDay = 6;
}
if (iStartDay == Calendar.SUNDAY) {
iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
if (iDay < 0)
iDay = 6;
}
calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
}
/**
* 描述:更新日历.
*/
private void updateCalendar() {
final boolean bIsSelection = (calSelected.getTimeInMillis() != 0);
final int iSelectedYear = calSelected.get(Calendar.YEAR);
final int iSelectedMonth = calSelected.get(Calendar.MONTH);
final int iSelectedDay = calSelected.get(Calendar.DAY_OF_MONTH);
boolean isThisMonth = false;
//今天在当前月,则去掉默认选中的1号
if (calToday.get(Calendar.YEAR) == iSelectedYear) {
if (calToday.get(Calendar.MONTH) == iSelectedMonth) {
isThisMonth = true;
}
}
calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());
for (int i = 0; i < mCalendarCells.size(); i++) {
CalendarCell dayCell = mCalendarCells.get(i);
//
final int iYear = calCalendar.get(Calendar.YEAR);
final int iMonth = calCalendar.get(Calendar.MONTH);
final int iDay = calCalendar.get(Calendar.DAY_OF_MONTH);
final int iDayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);
// 判断是否当天
boolean bToday = false;
// 是否被选中
boolean bSelected = false;
// check holiday
boolean bHoliday = false;
// 是否有记录
boolean hasRecord = false;
if (calToday.get(Calendar.YEAR) == iYear) {
if (calToday.get(Calendar.MONTH) == iMonth) {
if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {
bToday = true;
}
}
}
if ((iDayOfWeek == Calendar.SATURDAY) || (iDayOfWeek == Calendar.SUNDAY)){
bHoliday = true;
}
if ((iMonth == Calendar.JANUARY) && (iDay == 1)){
bHoliday = true;
}
if (bIsSelection){
if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth) && (iSelectedYear == iYear)) {
bSelected = true;
}else{
bSelected = false;
}
}
if(iDay==1 && isThisMonth){
bSelected = false;
}
dayCell.setThisCellDate(iYear, iMonth, iDay, bToday,bSelected, bHoliday,currentMonth, hasRecord);
calCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
invalidate();
}
/**
* 描述:更新日历.
*/
private void initCalendar() {
final boolean bIsSelection = (calSelected.getTimeInMillis() != 0);
final int iSelectedYear = calSelected.get(Calendar.YEAR);
final int iSelectedMonth = calSelected.get(Calendar.MONTH);
final int iSelectedDay = calSelected.get(Calendar.DAY_OF_MONTH);
calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());
for (int i = 0; i < mCalendarCells.size(); i++) {
CalendarCell dayCell = mCalendarCells.get(i);
//
final int iYear = calCalendar.get(Calendar.YEAR);
final int iMonth = calCalendar.get(Calendar.MONTH);
final int iDay = calCalendar.get(Calendar.DAY_OF_MONTH);
final int iDayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);
// 判断是否当天
boolean bToday = false;
// 是否被选中
boolean bSelected = false;
// check holiday
boolean bHoliday = false;
if (calToday.get(Calendar.YEAR) == iYear) {
if (calToday.get(Calendar.MONTH) == iMonth) {
if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {
bToday = true;
}
}
}
if ((iDayOfWeek == Calendar.SATURDAY) || (iDayOfWeek == Calendar.SUNDAY)){
bHoliday = true;
}
if ((iMonth == Calendar.JANUARY) && (iDay == 1)){
bHoliday = true;
}
if (bIsSelection){
if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth) && (iSelectedYear == iYear)) {
bSelected = true;
}else{
bSelected = false;
}
}
dayCell.setThisCellDate(iYear, iMonth, iDay, bToday,bSelected, bHoliday,currentMonth, false);
calCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
invalidate();
}
/**
* Sets the on item click listener.
*
* @param mAbOnItemClickListener the new on item click listener
*/
public void setOnItemClickListener(
AbOnItemClickListener mAbOnItemClickListener) {
this.mOnItemClickListener = mAbOnItemClickListener;
}
/**
* Sets the header height.
*
* @param height the new header height
*/
public void setHeaderHeight(int height) {
headerHeight = height;
mLinearLayoutHeader.removeAllViews();
mCalendarHeader.setLayoutParams(new LayoutParams(width,headerHeight));
mLinearLayoutHeader.addView(mCalendarHeader,new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
this.invalidate();
}
/**
* Sets the header text size.
*
* @param size the new header text size
*/
public void setHeaderTextSize(int size) {
mCalendarHeader.setTextSize(size);
this.invalidate();
}
/**
* Rebuild calendar.
*
* @param calendar the calendar
*/
public void rebuildCalendar(Calendar calendar) {
//初始化选中1号
calSelected.setTimeInMillis(calendar.getTimeInMillis());
initRow();
initStartDateForMonth();
updateCalendar();
}
/** 点击日历,触发事件. */
private AbOnItemClickListener mOnDayCellClick = new AbOnItemClickListener(){
@Override
public void onClick(int position) {
CalendarCell mCalendarCell = mCalendarCells.get(position);
if(mCalendarCell.isActiveMonth()){
calSelected.setTimeInMillis(mCalendarCell.getThisCellDate().getTimeInMillis());
for(int i=0;i<mCalendarCells.size();i++){
CalendarCell mCalendarCellOther = mCalendarCells.get(i);
mCalendarCellOther.setSelected(false);
}
mCalendarCell.setSelected(true);
if(mOnItemClickListener!=null){
mOnItemClickListener.onClick(position);
}
}
}
};
/**
* 描述:设置标题背景.
*
* @param resid the new header background resource
*/
public void setHeaderBackgroundResource(int resid){
mCalendarHeader.setHeaderBackgroundResource(resid);
}
/**
* 描述:根据索引获取选择的日期.
*
* @param position the position
* @return the str date at position
*/
public String getStrDateAtPosition(int position){
CalendarCell mCalendarCell = mCalendarCells.get(position);
Calendar calendar = mCalendarCell.getThisCellDate();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)+1;
int day = calendar.get(Calendar.DATE);
return year+"-"+month+"-"+day;
}
/**
* 描述:获取这个日历的总日期数.
*
* @return the calendar cell size
*/
public int getCalendarCellSize(){
return mCalendarCells.size();
}
/**
* 描述:获取当前日历的所有条目.
*
* @return the calendar cells
*/
public ArrayList<CalendarCell> getCalendarCells() {
return mCalendarCells;
}
/**
* 描述:获取选中的日期,默认为今天.
*
* @return the cal selected
*/
public String getCalSelected() {
final int iYear = calSelected.get(Calendar.YEAR);
final int iMonth = calSelected.get(Calendar.MONTH)+1;
final int iDay = calSelected.get(Calendar.DAY_OF_MONTH);
return iYear+"-"+iMonth+"-"+iDay;
}
/**
* 条目点击接口.
*
* @see AbOnItemClickEvent
*/
public interface AbOnItemClickListener {
/**
* 描述:点击事件.
* @param position 索引
*/
public void onClick(int position);
}
}