/**
* 描述:自定义日历控件
* The Class CalendarView.
* @author LiuZiWei
* @date 2014-4-28
*/
@SuppressLint("ViewConstructor")
public class CalendarView extends LinearLayout {
/** The context. */
private Context context;
/** 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 = 200;
/** 星期头的行高. */
private int headerHeight = MY.PHONEWIDTH/7-10;
//行高
/** The row height. */
private int rowHeight = MY.PHONEWIDTH/7-10;
//每个单元格的宽度
/** The cell width. */
private int cellWidth = MY.PHONEWIDTH/7;
// 日期变量
/** The cal start date. */
public static Calendar calStartDate = Calendar.getInstance();
/** The cal today. */
private Calendar calToday = Calendar.getInstance();
/** The cal selected. */
private static Calendar calSelected = null;
//累计日期
/** The cal calendar. */
private Calendar calCalendar = Calendar.getInstance();
/** The current month. */
private int currentMonth = 0;
//本日历的第一个单元格的星期
/** The first day of week. */
private int firstDayOfWeek = Calendar.SUNDAY;
//今天
private int Teday;
private int ThisMonth;
//得到需要特别显示的字的数据
private ArrayList<String> numberlist = new ArrayList<String>();
//当前显示的单元格
/** The m calendar cells. */
private static 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,ArrayList<String> array) {
this(context,array, null);
}
/**
* Instantiates a new calendar view.
*
* @param context the context
* @param attrs the attrs
*/
@SuppressWarnings("deprecation")
public CalendarView(Context context,ArrayList<String> array,AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.numberlist=array;
new LinearLayout.LayoutParams(LayoutParams.MATCH_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();
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;
//初始化选中今天
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);
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 isOrage=false;
boolean isLatDay=false;
// 判断是否当天
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) {
ThisMonth=iMonth;
if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {
Teday=iDay;
bToday = true;
}else if (calToday.get(Calendar.DAY_OF_MONTH)>iDay) {
//判断是不是过去的日期
isLatDay = true;
}
}
}
//判断应该变成橘色的数据
if(null!=numberlist){
if (calToday.get(Calendar.YEAR) == iYear) {
if (calToday.get(Calendar.MONTH) == iMonth) {
for(int j=0;j<numberlist.size();j++){
if(Integer.parseInt(numberlist.get(j))==iDay){
isOrage=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, isLatDay,isOrage,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 isOrage=false;
boolean isLatDay=false;
// 判断是否当天
boolean bToday = false;
// 是否被选中
boolean bSelected = false;
// check holiday
boolean bHoliday = false;
if (calToday.get(Calendar.YEAR) == iYear) {
if (calToday.get(Calendar.MONTH) == iMonth) {
ThisMonth=iMonth;
if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {
Teday=iDay;
bToday = true;
}else if (calToday.get(Calendar.DAY_OF_MONTH)>iDay) {
isLatDay=true;
}
}
}
//判断应该变成橘色的数据
if(null!=numberlist){
if (calToday.get(Calendar.YEAR) == iYear) {
if (calToday.get(Calendar.MONTH) == iMonth) {
for(int j=0;j<numberlist.size();j++){
if(Integer.parseInt(numberlist.get(j))==iDay){
isOrage=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,isLatDay,isOrage,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.MATCH_PARENT, LayoutParams.MATCH_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() && mCalendarCell.getiDateMonth()==ThisMonth && mCalendarCell.getiDateDay()>Teday) || (mCalendarCell.isActiveMonth() && mCalendarCell.getiDateMonth()!=ThisMonth)){
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);
}
public void setHeaderBackgroundColor(int resid){
mCalendarHeader.setHeaderBackgroundColor(resid);
}
/**
* 描述:根据索引获取选择的日期.
*
* @param position the position
* @return the str date at position
*/
public static 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);
final int iWeek=calSelected.get(Calendar.DAY_OF_WEEK)-1;
String week;
switch (iWeek) {
case 1:
week="星期一";
break;
case 2:
week="星期二";
break;
case 3:
week="星期三";
break;
case 4:
week="星期四";
break;
case 5:
week="星期五";
break;
case 6:
week="星期六";
break;
default:
week="星期日";
break;
}
return year+"-"+month+"-"+day+"-"+week;
}
/**
* 描述:获取这个日历的总日期数.
*
* @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);
final int iWeek=calSelected.get(Calendar.DAY_OF_WEEK)-1;
String week;
switch (iWeek) {
case 1:
week="星期一";
break;
case 2:
week="星期二";
break;
case 3:
week="星期三";
break;
case 4:
week="星期四";
break;
case 5:
week="星期五";
break;
case 6:
week="星期六";
break;
default:
week="星期日";
break;
}
return iYear+"-"+iMonth+"-"+iDay+"-"+week;
}
}
自定义日历控件
最新推荐文章于 2016-02-26 15:37:14 发布