| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
c6b4
10年前发布

Android系统自定义实现日历控件

注:此功能在在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>