自定义日历控件

/**
 * 描述:自定义日历控件
 * 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;
	}

 	
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值