清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
注:此功能在在Activity中,由三大块组成:头(上月按扭,下月按扭,当前年月文本),日历块(星期区域,日期区域),描述区域 Activity: /** * Android实现日历控件 * 注:Calendar时间与现在实的时间在月份上需要+1,因为月份是0-11 */ public class CalenderActivity extends Activity { private ArrayList<DateWidgetDayView> days = new ArrayList<DateWidgetDayView>(); //颜色代码常量 public static int Calendar_WeekBgColor = 0; public static int Calendar_DayBgColor = 0; public static int IsHoliday_BgColor = 0; public static int UnPresentMonth_FontColor = 0; public static int IsPresentMonth_FontColor = 0; public static int IsToday_BgColor = 0; public static int Special_Reminder = 0; public static int Common_Reminder = 0; public static int Calendar_WeekFontColor = 0; /** * 表格中的第一天,一般上月的某一天 */ public static Calendar mFirstDateOfPanel = Calendar.getInstance(); private Calendar mTodayDate = Calendar.getInstance();// 初始日期,即当天 private Calendar mSelectedDate = Calendar.getInstance();//选中的日期,如果未选中则为1970-1-1 private Calendar mViewDate = Calendar.getInstance(); // 当前操作日期 private int firstDayOfWeek = Calendar.SUNDAY;// 是星期日 private int currentMonth = 0; private int currentYear = 0; private int displayWidth = 0;// 屏幕总宽度 private int cell_Width = 0; // 日期单元格宽度 private int cell_Height = 35; // 日期单元格高度 // 页面控件 TextView currentYAndM = null; Button preMonthButton = null; Button nextMonthButton = null; LinearLayout mainLayout = null; LinearLayout calendarLayout = null; LinearLayout contentLayout = null; TextView contentText = null; // 数据源 Boolean[] msgs = null; Calendar startDate = null;//表格的第一天的日期 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.calendar_main); this.viewModel = new BlogViewModel(this); // 获得屏幕宽和高,并計算出屏幕寬度分七等份的大小 WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); displayWidth = display.getWidth(); cell_Width = displayWidth / 7 + 1; // 制定布局文件,并设置属性 mainLayout = (LinearLayout) this.findViewById(R.id.date_calender_framelayout); currentYAndM = (TextView) findViewById(R.id.Top_Date); preMonthButton = (Button) findViewById(R.id.btn_pre_month); nextMonthButton = (Button) findViewById(R.id.btn_next_month); preMonthButton.setOnClickListener(new OnClickPreMonthListener()); nextMonthButton.setOnClickListener(new OnClickNextMonthListener()); // 计算本月日历中的第一天(一般是上月的某天),并更新日历 mFirstDateOfPanel = getCalendarStartDate(); this.mTodayDate = getTodayDate(); this.startDate = getStartDate(); /* * 初始化日期视图 * Calendar部分 */ View calendarView = generateCalendarView(); this.mainLayout.addView(calendarView); //刷新日期视图 this.refreshCalendar(); /* * Description 部分 */ ScrollView view = new ScrollView(this); contentLayout = createLayout(LinearLayout.VERTICAL); contentLayout.setPadding(5, 2, 0, 0); contentText = new TextView(this); contentText.setTextColor(Color.BLACK); contentText.setTextSize(18); contentLayout.addView(contentText); LinearLayout.LayoutParams Param1 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); view.addView(contentLayout, Param1); mainLayout.setBackgroundColor(Color.WHITE); mainLayout.addView(view); /* 新建线程 new Thread() { @Override public void run() { int day = getIndexFromDates(mTodayDate, startDate); Log.i("sys", "初始时 day = "+day); } }.start();*/ Calendar_WeekBgColor = this.getResources().getColor(R.color.Calendar_WeekBgColor); Calendar_DayBgColor = this.getResources().getColor(R.color.Calendar_DayBgColor); IsHoliday_BgColor = this.getResources().getColor(R.color.isHoliday_BgColor); UnPresentMonth_FontColor = this.getResources().getColor(R.color.unPresentMonth_FontColor); IsPresentMonth_FontColor = this.getResources().getColor(R.color.isPresentMonth_FontColor); IsToday_BgColor = this.getResources().getColor(R.color.isToday_BgColor); Special_Reminder = this.getResources().getColor(R.color.specialReminder); Common_Reminder = this.getResources().getColor(R.color.commonReminder); Calendar_WeekFontColor = this.getResources().getColor(R.color.Calendar_WeekFontColor); } protected String getDateShortString(Calendar date) { String returnString = date.get(Calendar.YEAR) + "-"; returnString += date.get(Calendar.MONTH) + 1 + "-"; returnString += date.get(Calendar.DAY_OF_MONTH); return returnString; } /** * Return the Date's index of {@link returnDate} from {@link datesList}; * First is Today's index * * @param now * today * @param returnDate * click date * @return */ private int getIndexFromDates(Calendar now, Calendar returnDate) { Calendar cNow = (Calendar) now.clone(); Calendar cReturnDate = (Calendar) returnDate.clone(); CalenderUtil.setTimeToMidnight(cNow); CalenderUtil.setTimeToMidnight(cReturnDate); long todayMs = cNow.getTimeInMillis(); long returnMs = cReturnDate.getTimeInMillis(); long intervalMs = todayMs - returnMs; int index = CalenderUtil.millisecondsToDays(intervalMs); Log.i("sys", "Index = " + index); return index; } /** * 生成日期视图 即初始化calendarLayout * * @return */ private View generateCalendarView() { calendarLayout = createLayout(LinearLayout.VERTICAL); // layContent.setPadding(1, 0, 1, 0); calendarLayout.setBackgroundColor(Color.argb(255, 105, 105, 103)); calendarLayout.addView(generateCalendarWeekRows()); days.clear(); for (int iRow = 0; iRow < 6; iRow++) { calendarLayout.addView(generateCalendarDayRows()); } return calendarLayout; } /** * 生成星期View * * @return View */ private View generateCalendarWeekRows() { LinearLayout weekLayoutRow = createLayout(LinearLayout.HORIZONTAL); weekLayoutRow.setBackgroundColor(Color.argb(255, 207, 207, 205)); for (int iDay = 0; iDay < 7; iDay++) { DateWidgetWeekView dayView = new DateWidgetWeekView(this, cell_Width, cell_Height); final int iWeekDay = CalenderUtil.getWeekDay(iDay, firstDayOfWeek); dayView.setData(iWeekDay); weekLayoutRow.addView(dayView); } return weekLayoutRow; } /** * 生成日期行View * * @return View */ private View generateCalendarDayRows() { LinearLayout layRow = createLayout(LinearLayout.HORIZONTAL); //TODO 日期数据消息给添加属性 for (int iDay = 0; iDay < 7; iDay++) { DateWidgetDayView dateDayView = new DateWidgetDayView(this, cell_Width, cell_Width); dateDayView.setItemClick(mOnDayCellClick); days.add(dateDayView); layRow.addView(dateDayView); } return layRow; } /** * 由于本日历上的日期都是从周一开始的,此方法可推算出上月在本月日历中显示的天数 计算出本月第一行1号前的空格数 */ private void updateStartDateForPanel() { currentMonth = mFirstDateOfPanel.get(Calendar.MONTH); currentYear = mFirstDateOfPanel.get(Calendar.YEAR); mFirstDateOfPanel.set(Calendar.DAY_OF_MONTH, 1); mFirstDateOfPanel.set(Calendar.HOUR_OF_DAY, 0); mFirstDateOfPanel.set(Calendar.MINUTE, 0); mFirstDateOfPanel.set(Calendar.SECOND, 0); // 显示当前是的年月在Header updateCurrentMonthDisplay(); int iDay = 0;// 前面的空格数 int iStartDay = firstDayOfWeek;// 当天的星期角标 if (iStartDay == Calendar.MONDAY) { iDay = mFirstDateOfPanel.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY; if (iDay < 0) iDay = 6; } if (iStartDay == Calendar.SUNDAY) { iDay = mFirstDateOfPanel.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY; if (iDay < 0) iDay = 6; } mFirstDateOfPanel.add(Calendar.DAY_OF_WEEK, -iDay);// 得出-2,即前面从上月30号开始 } /** * 更新日历数据并设置日期 * 给days中的DateWidgetDayView元素添加Text */ private void refreshCalendar() { DateWidgetDayView dayView = null; boolean isSelected = false; final boolean bIsSelection = (mSelectedDate.getTimeInMillis() != 0); final int iSelectedYear = mSelectedDate.get(Calendar.YEAR); final int iSelectedMonth = mSelectedDate.get(Calendar.MONTH); final int iSelectedDay = mSelectedDate.get(Calendar.DAY_OF_MONTH); //取得表格中的第一天(一般为上月) mViewDate.setTimeInMillis(mFirstDateOfPanel.getTimeInMillis()); for (int i = 0; i < days.size(); i++) { final int iYear = mViewDate.get(Calendar.YEAR); final int iMonth = mViewDate.get(Calendar.MONTH); final int iDay = mViewDate.get(Calendar.DAY_OF_MONTH); final int iDayOfWeek = mViewDate.get(Calendar.DAY_OF_WEEK); dayView = days.get(i); // Check isToday boolean isToday = false; if (mTodayDate.get(Calendar.YEAR) == iYear && mTodayDate.get(Calendar.MONTH) == iMonth && mTodayDate.get(Calendar.DAY_OF_MONTH) == iDay) { isToday = true; } // Check isHoliday boolean isHoliday = false; if ((iDayOfWeek == Calendar.SATURDAY) || (iDayOfWeek == Calendar.SUNDAY)) isHoliday = true; /*if ((iMonth == Calendar.JANUARY) && (iDay == 1)) isHoliday = true;*///在格里高利历和罗马儒略历中一年中的第一个月是 JANUARY,它为 0;最后一个月取决于一年中的月份数。 // Check isSelected isSelected = false; if (bIsSelection) if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth) && (iSelectedYear == iYear)) { isSelected = true; } dayView.setSelected(isSelected); // Check hasMSG boolean hasMSG = false; if (msgs != null && msgs[i] == true ){ //TODO } if (isSelected){ dayView.setFocusable(true); } dayView.setData(iYear, iMonth, iDay, isToday, isHoliday, currentMonth, hasMSG); mViewDate.add(Calendar.DAY_OF_MONTH, 1); Log.i("sys", "mViewDate : "+iYear+"-"+iMonth+"-"+iDay); Log.i("sys", "mFirstDateOfPanel : "+mFirstDateOfPanel.get(Calendar.YEAR)+"-"+mFirstDateOfPanel.get(Calendar.MONTH)+"-"+mFirstDateOfPanel.get(Calendar.DAY_OF_MONTH)); } Log.i("sys", "mSelectedDate : "+iSelectedYear+"-"+iSelectedMonth+"-"+iSelectedDay); Log.i("sys", "startDate : "+startDate.get(Calendar.YEAR)+"-"+startDate.get(Calendar.MONTH)+"-"+startDate.get(Calendar.DAY_OF_MONTH)); calendarLayout.invalidate(); } /** * 设置当天日期和第并计算出前面第一个星期天的日期{@link mFirstDateOfPanel} * @return */ private Calendar getCalendarStartDate() { mTodayDate.setTimeInMillis(System.currentTimeMillis()); mTodayDate.setFirstDayOfWeek(firstDayOfWeek); // 如果没有选中日期,则设置当前日期为 ? if (mSelectedDate.getTimeInMillis() == 0) { mFirstDateOfPanel.setTimeInMillis(System.currentTimeMillis()); mFirstDateOfPanel.setFirstDayOfWeek(firstDayOfWeek); } else { mFirstDateOfPanel.setTimeInMillis(mSelectedDate.getTimeInMillis()); mFirstDateOfPanel.setFirstDayOfWeek(firstDayOfWeek); } updateStartDateForPanel(); return mFirstDateOfPanel; } /** * 得到当前日历表中的第一天 * * @return Calendar */ public Calendar getStartDate() { int iDay = 0; Calendar cal_Now = Calendar.getInstance(); cal_Now.set(Calendar.DAY_OF_MONTH, 1); cal_Now.set(Calendar.HOUR_OF_DAY, 0); cal_Now.set(Calendar.MINUTE, 0); cal_Now.set(Calendar.SECOND, 0); cal_Now.setFirstDayOfWeek(Calendar.SUNDAY); iDay = cal_Now.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY; if (iDay < 0) { iDay = 6; } cal_Now.add(Calendar.DAY_OF_WEEK, -iDay); return cal_Now; } public Calendar getTodayDate() { Calendar cal_Today = Calendar.getInstance(); cal_Today.set(Calendar.HOUR_OF_DAY, 0); cal_Today.set(Calendar.MINUTE, 0); cal_Today.set(Calendar.SECOND, 0); cal_Today.setFirstDayOfWeek(Calendar.MONDAY); return cal_Today; } /** * 更新日历标题上显示的年月 */ private void updateCurrentMonthDisplay() { String date = mFirstDateOfPanel.get(Calendar.YEAR) + "年" + (mFirstDateOfPanel.get(Calendar.MONTH) + 1) + "月"; currentYAndM.setText(date); } /** * 点击上月按钮,触发事件 * @author Win7 */ // 生成布局LinearLayout private LinearLayout createLayout(int iOrientation) { LinearLayout lay = new LinearLayout(this); lay.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT)); lay.setOrientation(iOrientation); return lay; } class OnClickPreMonthListener implements OnClickListener { @Override public void onClick(View v) { contentText.setText("aaaa"); mSelectedDate.setTimeInMillis(0); currentMonth--; if (currentMonth == -1) { currentMonth = 11; currentYear--; } mFirstDateOfPanel.set(Calendar.DAY_OF_MONTH, 1); mFirstDateOfPanel.set(Calendar.MONTH, currentMonth); mFirstDateOfPanel.set(Calendar.YEAR, currentYear); mFirstDateOfPanel.set(Calendar.HOUR_OF_DAY, 0); mFirstDateOfPanel.set(Calendar.MINUTE, 0); mFirstDateOfPanel.set(Calendar.SECOND, 0); mFirstDateOfPanel.set(Calendar.MILLISECOND, 0); updateStartDateForPanel(); startDate = (Calendar) mFirstDateOfPanel.clone(); // 新建线程 new Thread() { @Override public void run() { int day = getIndexFromDates(mTodayDate, startDate); //day是算出当前显示的月份面版第一天与当天的天数 Log.i("sys", "点击上月时 day = "+day); } }.start(); refreshCalendar(); } } /** * 点击下月按钮,触发事件 * @author Win7 */ class OnClickNextMonthListener implements OnClickListener { @Override public void onClick(View v) { contentText.setText(""); mSelectedDate.setTimeInMillis(0); currentMonth++; if (currentMonth == 12) { currentMonth = 0; currentYear++; } mFirstDateOfPanel.set(Calendar.DAY_OF_MONTH, 1); mFirstDateOfPanel.set(Calendar.MONTH, currentMonth); mFirstDateOfPanel.set(Calendar.YEAR, currentYear); updateStartDateForPanel(); startDate = (Calendar) mFirstDateOfPanel.clone(); // 新建线程 new Thread() { @Override public void run() { int day = 5; Log.i("sys", "点击下月时 day = "+day); } }.start(); refreshCalendar(); } } // 点击日历,触发事件 private DateWidgetDayView.OnDateItemClickListener mOnDayCellClick = new DateWidgetDayView.OnDateItemClickListener() { public void OnClick(DateWidgetDayView item) { mSelectedDate.setTimeInMillis(item.getDate().getTimeInMillis()); int day = getIndexFromDates(mSelectedDate, startDate); contentText.setText(getDateShortString(mSelectedDate)); contentText.setText("无数据"); Log.i("sys", "mFirstDateOfPanel=" + mFirstDateOfPanel.get(Calendar.DATE) + " calCalendar=" + mViewDate.get(Calendar.DATE) + " mTodayDate=" + mTodayDate.get(Calendar.DATE) + " mSelectedDate=" + mSelectedDate.get(Calendar.DATE) +" day = "+day); item.setSelected(true); refreshCalendar(); } }; @Deprecated public Calendar getEndDate(Calendar startDate) { // Calendar end = GetStartDate(enddate); Calendar endDate = Calendar.getInstance(); endDate = (Calendar) startDate.clone(); endDate.add(Calendar.DAY_OF_MONTH, 41); return endDate; } } 星期View: public class DateWidgetWeekView extends View { // 字体大小 private final static int fTextSize = 22; private Paint pt = new Paint(); private RectF rect = new RectF(); private int iWeekDay = -1; public DateWidgetWeekView(Context context, int iWidth, int iHeight) { super(context); setLayoutParams(new LayoutParams(iWidth, iHeight)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置矩形大小 rect.set(0, 0, this.getWidth(), this.getHeight()); rect.inset(1, 1); // 绘制日历头部 drawDayHeader(canvas); } private void drawDayHeader(Canvas canvas) { // 画矩形,并设置矩形画笔的颜色 pt.setColor(CalenderActivity.Calendar_WeekBgColor); canvas.drawRect(rect, pt); // 写入日历头部,设置画笔参数 pt.setTypeface(null); pt.setTextSize(fTextSize); pt.setAntiAlias(true); pt.setFakeBoldText(true); pt.setColor(CalenderActivity.Calendar_WeekFontColor); // draw day name final String sDayName = CalenderUtil.getWeekDayName(iWeekDay); final int iPosX = (int) rect.left + ((int) rect.width() >> 1) - ((int) pt.measureText(sDayName) >> 1); final int iPosY = (int) (this.getHeight() - (this.getHeight() - getTextHeight()) / 2 - pt .getFontMetrics().bottom); canvas.drawText(sDayName, iPosX, iPosY, pt); } // 得到字体高度 private int getTextHeight() { return (int) (-pt.ascent() + pt.descent()); } // 得到一星期的第几天的文本标记 public void setData(int iWeekDay) { this.iWeekDay = iWeekDay; } } 日期View: /** * 日历控件单元格绘制类 * @Description: 日历控件单元格绘制类 * @FileName: DateWidgetDayView.java */ public class DateWidgetDayView extends View { // 字体大小 private static final int fTextSize = 28; // 基本元素 private OnDateItemClickListener itemClick = null; private Paint mPaint = new Paint(); private RectF rect = new RectF(); private String sDate = ""; // 当前日期 private int iDateYear = 0; private int iDateMonth = 0; private int iDateDay = 0; // 布尔变量 private boolean hasSelected = false; private boolean isActiveMonth = false; private boolean isToday = false; private boolean isTouchedDown = false; private boolean isHoliday = false; private boolean hasMSG = false; public static int ANIM_ALPHA_DURATION = 100; public interface OnDateItemClickListener { public void OnClick(DateWidgetDayView item); } // 构造函数 public DateWidgetDayView(Context context, int iWidth, int iHeight) { super(context); setFocusable(true); setLayoutParams(new LayoutParams(iWidth, iHeight)); } // 取变量值 public Calendar getDate() { Calendar calDate = Calendar.getInstance(); calDate.clear(); calDate.set(Calendar.YEAR, iDateYear); calDate.set(Calendar.MONTH, iDateMonth); calDate.set(Calendar.DAY_OF_MONTH, iDateDay); return calDate; } // 是否有消息 public boolean hasMSG() { return this.hasMSG; } // 是否假期 public boolean isHoliday() { return this.isHoliday; } // 设置变量值 public void setData(int iYear, int iMonth, int iDay, Boolean bToday, Boolean bHoliday, int iActiveMonth, boolean hasRecord) { iDateYear = iYear; iDateMonth = iMonth; iDateDay = iDay; this.sDate = Integer.toString(iDateDay); this.isActiveMonth = (iDateMonth == iActiveMonth); this.isToday = bToday; this.isHoliday = bHoliday; this.hasMSG = hasRecord; } // 重载绘制方法 @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); rect.set(0, 0, this.getWidth(), this.getHeight()); rect.inset(1, 1); final boolean bFocused = IsViewFocused(); drawDayView(canvas, bFocused); drawDayNumber(canvas); } public boolean IsViewFocused() { return (this.isFocused() || isTouchedDown); } // 绘制日历方格 private void drawDayView(Canvas canvas, boolean bFocused) { if (hasSelected || bFocused) { LinearGradient lGradBkg = null; if (bFocused) { lGradBkg = new LinearGradient(rect.left, 0, rect.right, 0, 0xffaa5500, 0xffffddbb, Shader.TileMode.CLAMP); } if (hasSelected) { lGradBkg = new LinearGradient(rect.left, 0, rect.right, 0, 0xff225599, 0xffbbddff, Shader.TileMode.CLAMP); } if (lGradBkg != null) { mPaint.setShader(lGradBkg); canvas.drawRect(rect, mPaint); } mPaint.setShader(null); } else { mPaint.setColor(getColorBkg(isHoliday, isToday)); canvas.drawRect(rect, mPaint); } if(isHoliday){ mPaint.setColor(CalenderActivity.IsHoliday_BgColor); canvas.drawRect(rect, mPaint); } if (hasMSG) { markHasMSGReminder(canvas, CalenderActivity.Special_Reminder); } // else if (!hasRecord && !bToday && !bSelected) { // CreateReminder(canvas, Calendar_TestActivity.Calendar_DayBgColor); // } } // 绘制日历中的数字 public void drawDayNumber(Canvas canvas) { // draw day number mPaint.setTypeface(null); mPaint.setAntiAlias(true); mPaint.setShader(null); mPaint.setFakeBoldText(true); mPaint.setTextSize(fTextSize); mPaint.setColor(CalenderActivity.IsPresentMonth_FontColor); mPaint.setUnderlineText(false); if (!isActiveMonth) mPaint.setColor(CalenderActivity.UnPresentMonth_FontColor); if (isToday) mPaint.setUnderlineText(true); final int iPosX = (int) rect.left + ((int) rect.width() >> 1) - ((int) mPaint.measureText(sDate) >> 1); final int iPosY = (int) (this.getHeight() - (this.getHeight() - getTextHeight()) / 2 - mPaint .getFontMetrics().bottom); canvas.drawText(sDate, iPosX, iPosY, mPaint); mPaint.setUnderlineText(false); } // 得到字体高度 private int getTextHeight() { return (int) (-mPaint.ascent() + mPaint.descent()); } // 根据条件返回不同颜色值 public static int getColorBkg(boolean bHoliday, boolean bToday) { if (bToday) return CalenderActivity.IsToday_BgColor; // if (bHoliday) //如需周末有特殊背景色,可去掉注释 // return Calendar_TestActivity.isHoliday_BgColor; return CalenderActivity.Calendar_DayBgColor; } // 设置是否被选中 @Override public void setSelected(boolean bEnable) { if (this.hasSelected != bEnable) { this.hasSelected = bEnable; this.invalidate(); } } public void setItemClick(OnDateItemClickListener itemClick) { this.itemClick = itemClick; } public void doItemClick() { if (itemClick != null) itemClick.OnClick(this); } // 点击事件 @Override public boolean onTouchEvent(MotionEvent event) { boolean bHandled = false; if (event.getAction() == MotionEvent.ACTION_DOWN) { bHandled = true; isTouchedDown = true; invalidate(); startAlphaAnimIn(DateWidgetDayView.this); } if (event.getAction() == MotionEvent.ACTION_CANCEL) { bHandled = true; isTouchedDown = false; invalidate(); } if (event.getAction() == MotionEvent.ACTION_UP) { bHandled = true; isTouchedDown = false; invalidate(); doItemClick(); } return bHandled; } // 点击事件 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { boolean bResult = super.onKeyDown(keyCode, event); if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) || (keyCode == KeyEvent.KEYCODE_ENTER)) { doItemClick(); } return bResult; } // 不透明度渐变 public static void startAlphaAnimIn(View view) { AlphaAnimation anim = new AlphaAnimation(0.5F, 1); anim.setDuration(ANIM_ALPHA_DURATION); anim.startNow(); view.startAnimation(anim); } //右上角画倒三角 public void markHasMSGReminder(Canvas canvas, int Color) { mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setColor(Color); Path path = new Path(); path.moveTo(rect.right - rect.width() / 4, rect.top); path.lineTo(rect.right, rect.top); path.lineTo(rect.right, rect.top + rect.width() / 4); path.lineTo(rect.right - rect.width() / 4, rect.top); path.close(); canvas.drawPath(path, mPaint); } } 工具类: public class CalenderUtil { private final static String[] vecStrWeekDayNames = getWeekDayNames(); private static String[] getWeekDayNames() { String[] vec = new String[10]; vec[Calendar.SUNDAY] = "星期日"; vec[Calendar.MONDAY] = "星期一"; vec[Calendar.TUESDAY] = "星期二"; vec[Calendar.WEDNESDAY] = "星期三"; vec[Calendar.THURSDAY] = "星期四"; vec[Calendar.FRIDAY] = "星期五"; vec[Calendar.SATURDAY] = "星期六"; return vec; } public static String getWeekDayName(int iDay) { return vecStrWeekDayNames[iDay]; } public static int getWeekDay(int index, int iFirstDayOfWeek) { int iWeekDay = -1; if (iFirstDayOfWeek == Calendar.MONDAY) { iWeekDay = index + Calendar.MONDAY; if (iWeekDay > Calendar.SATURDAY) iWeekDay = Calendar.SUNDAY; } if (iFirstDayOfWeek == Calendar.SUNDAY) { iWeekDay = index + Calendar.SUNDAY; } return iWeekDay; } /** * Calculate the days with milliseconds * @param intervalMs * @return */ public static int millisecondsToDays(long intervalMs) { return Math.round((intervalMs / (1000 * 86400))); } /** * Return the milliseconds from 1970 to just * @param calendar */ public static void setTimeToMidnight(Calendar calendar) { calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); } } calendar_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" android:orientation="vertical" > <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="60dip" android:background="#EDE8DD" > <TextView android:id="@+id/Top_Date" android:layout_width="150dip" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal|center" android:textColor="#424139" android:textSize="19sp" android:textStyle="bold" /> <Button android:id="@+id/btn_pre_month" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:background="@drawable/previous_month" android:text="" /> <Button android:id="@+id/btn_next_month" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="30dp" android:background="@drawable/next_month" android:text="" /> </RelativeLayout> <LinearLayout android:id="@+id/date_calender_framelayout" android:layout_height="fill_parent" android:layout_width="fill_parent" ></LinearLayout> </LinearLayout>