欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现自定义日历

程序员文章站 2022-07-11 18:37:30
自定义日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写) 注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如calendar.jav...

自定义日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)
注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如calendar.java 所在包为
cc.util.android.view,则需要再创建一个包cc.util.android.view.image 然后将图片拷贝进去

/****************从此出开始将代码拷贝到一个文件中*******************/
package cc.util.android.view;
 
import java.text.parseexception;
import java.text.simpledateformat;
import java.util.arraylist;
import java.util.calendar;
import java.util.date;
import java.util.list;
import java.util.locale;
import android.annotation.suppresslint;
import android.content.context;
import android.graphics.bitmapfactory;
import android.graphics.color;
import android.graphics.drawable.bitmapdrawable;
import android.graphics.drawable.drawable;
import android.graphics.drawable.statelistdrawable;
import android.text.textutils.truncateat;
import android.util.attributeset;
import android.view.gesturedetector;
import android.view.gesturedetector.ongesturelistener;
import android.view.gravity;
import android.view.motionevent;
import android.view.view;
import android.view.viewgroup;
import android.view.view.ontouchlistener;
import android.view.animation.animation;
import android.view.animation.animation.animationlistener;
import android.view.animation.translateanimation;
import android.widget.baseadapter;
import android.widget.gridview;
import android.widget.imagebutton;
import android.widget.linearlayout;
import android.widget.relativelayout;
import android.widget.textview;
import android.widget.viewflipper;
import android.widget.abslistview.layoutparams;
 
/**
 * 日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)
 * 
 * @author wangcccong
 * @version 1.406 create at: mon, 03 sep. 2014 
 * <br>update at: mon, 23 sep. 2014 
 *   新增日期标注和点击操作
 */
public class calendarview extends linearlayout implements ontouchlistener,
    animationlistener, ongesturelistener {
 
  /**
   * 点击日历
   */
  public interface oncalendarviewlistener {
    void oncalendaritemclick(calendarview view, date date);
  }
 
  /** 顶部控件所占高度 */
  private final static int top_height = 40;
  /** 日历item中默认id从0xff0000开始 */
  private final static int default_id = 0xff0000;
 
  // 判断手势用
  private static final int swipe_min_distance = 120;
  private static final int swipe_max_off_path = 250;
  private static final int swipe_threshold_velocity = 200;
 
  // 屏幕宽度和高度
  private int screenwidth;
 
  // 动画
  private animation slideleftin;
  private animation slideleftout;
  private animation sliderightin;
  private animation sliderightout;
  private viewflipper viewflipper;
  private gesturedetector mgesture = null;
 
  /** 上一月 */
  private gridview gview1;
  /** 当月 */
  private gridview gview2;
  /** 下一月 */
  private gridview gview3;
 
  boolean bisselection = false;// 是否是选择事件发生
  private calendar calstartdate = calendar.getinstance();// 当前显示的日历
  private calendar calselected = calendar.getinstance(); // 选择的日历
  private calendargridviewadapter gadapter;
  private calendargridviewadapter gadapter1;
  private calendargridviewadapter gadapter3;
 
  private linearlayout mmainlayout;
  private textview mtitle; // 显示年月
 
  private int imonthviewcurrentmonth = 0; // 当前视图月
  private int imonthviewcurrentyear = 0; // 当前视图年
 
  private static final int caltitlelayoutid = 66; // title布局id
  private static final int callayoutid = 55; // 日历布局id
  private context mcontext;
 
  /** 标注日期 */
  private final list<date> markdates;
 
  private oncalendarviewlistener mlistener;
 
  public calendarview(context context) {
    this(context, null);
  }
 
  public calendarview(context context, attributeset attrs) {
    super(context, attrs);
    // todo auto-generated constructor stub
    mcontext = context;
    markdates = new arraylist<date>();
    init();
  }
 
  // 初始化相关工作
  protected void init() {
    // 得到屏幕的宽度
    screenwidth = mcontext.getresources().getdisplaymetrics().widthpixels;
 
    // 滑动的动画
    slideleftin = new translateanimation(screenwidth, 0, 0, 0);
    slideleftin.setduration(400);
    slideleftin.setanimationlistener(this);
    slideleftout = new translateanimation(0, -screenwidth, 0, 0);
    slideleftout.setduration(400);
    slideleftout.setanimationlistener(this);
    sliderightin = new translateanimation(-screenwidth, 0, 0, 0);
    sliderightin.setduration(400);
    sliderightin.setanimationlistener(this);
    sliderightout = new translateanimation(0, screenwidth, 0, 0);
    sliderightout.setduration(400);
    sliderightout.setanimationlistener(this);
 
    // 手势操作
    mgesture = new gesturedetector(mcontext, this);
 
    // 获取到当前日期
    updatestartdateformonth();
    // 绘制界面
    setorientation(linearlayout.horizontal);
    mmainlayout = new linearlayout(mcontext);
    linearlayout.layoutparams main_params = new linearlayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    mmainlayout.setlayoutparams(main_params);
    mmainlayout.setgravity(gravity.center_horizontal);
    mmainlayout.setorientation(linearlayout.vertical);
    addview(mmainlayout);
 
    // 顶部控件
    generatetopview();
 
    // 中间显示星期
    generateweekgirdview();
 
    // 底部显示日历
    viewflipper = new viewflipper(mcontext);
    relativelayout.layoutparams fliper_params = new relativelayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    fliper_params.addrule(relativelayout.below, caltitlelayoutid);
    mmainlayout.addview(viewflipper, fliper_params);
    generateclaendargirdview();
 
    // 最下方的一条线条
    linearlayout br = new linearlayout(mcontext);
    br.setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4));
    linearlayout.layoutparams params_br = new linearlayout.layoutparams(
        layoutparams.match_parent, 3);
    mmainlayout.addview(br, params_br);
  }
 
  /** 生成顶部控件 */
  @suppresswarnings("deprecation")
  private void generatetopview() {
    // 顶部显示上一个下一个,以及当前年月
    relativelayout top = new relativelayout(mcontext);
    top.setbackgroundcolor(color.argb(0xff, 0x0e, 0x6b, 0xc2));
    linearlayout.layoutparams top_params = new linearlayout.layoutparams(
        layoutparams.match_parent,
        viewutil.dip2px(mcontext, top_height));
    top.setlayoutparams(top_params);
    mmainlayout.addview(top);
    // 左方按钮、中间日期显示、右方按钮
    mtitle = new textview(mcontext);
    android.widget.relativelayout.layoutparams title_params = new android.widget.relativelayout.layoutparams(
        android.widget.relativelayout.layoutparams.match_parent,
        android.widget.relativelayout.layoutparams.match_parent);
    mtitle.setlayoutparams(title_params);
    mtitle.settextcolor(color.white);
    mtitle.settextsize(18);
    mtitle.setfocusableintouchmode(true);
    mtitle.setmarqueerepeatlimit(-1);
    mtitle.setellipsize(truncateat.marquee);
    mtitle.setsingleline(true);
    mtitle.setgravity(gravity.center);
    mtitle.sethorizontallyscrolling(true);
    mtitle.settext("2014年9月");
    top.addview(mtitle);
 
    // 左方按钮
    imagebutton mleftview = new imagebutton(mcontext);
    statelistdrawable statelistdrawablel = new statelistdrawable();
    drawable ldrawablenor = new bitmapdrawable(mcontext.getresources(),
        bitmapfactory.decodestream(calendarview.class
            .getresourceasstream("image/left_arrow.png")));
    drawable ldrawablepre = new bitmapdrawable(mcontext.getresources(),
        bitmapfactory.decodestream(calendarview.class
            .getresourceasstream("image/left_arrow_pre.png")));
    statelistdrawablel.addstate(
        new int[] { -android.r.attr.state_pressed }, ldrawablenor);
    statelistdrawablel.addstate(new int[] { android.r.attr.state_pressed },
        ldrawablepre);
    mleftview.setbackgrounddrawable(statelistdrawablel);
 
    android.widget.relativelayout.layoutparams leftpp = new android.widget.relativelayout.layoutparams(
        viewutil.dip2px(mcontext, 25), viewutil.dip2px(mcontext, 22));
    leftpp.addrule(relativelayout.align_parent_left);
    leftpp.addrule(relativelayout.center_vertical, relativelayout.true);
    leftpp.setmargins(20, 0, 0, 0);
    mleftview.setlayoutparams(leftpp);
    mleftview.setonclicklistener(new onclicklistener() {
 
      @override
      public void onclick(view v) {
        // todo auto-generated method stub
        viewflipper.setinanimation(sliderightin);
        viewflipper.setoutanimation(sliderightout);
        viewflipper.showprevious();
        setprevviewitem();
      }
    });
    top.addview(mleftview);
 
    // 右方按钮
    imagebutton mrightview = new imagebutton(mcontext);
    statelistdrawable statelistdrawable = new statelistdrawable();
    drawable rdrawablenor = new bitmapdrawable(mcontext.getresources(),
        bitmapfactory.decodestream(calendarview.class
            .getresourceasstream("image/right_arrow.png")));
    drawable rdrawablepre = new bitmapdrawable(mcontext.getresources(),
        bitmapfactory.decodestream(calendarview.class
            .getresourceasstream("image/right_arrow_pre.png")));
    statelistdrawable.addstate(new int[] { -android.r.attr.state_pressed },
        rdrawablenor);
    statelistdrawable.addstate(new int[] { android.r.attr.state_pressed },
        rdrawablepre);
    mrightview.setbackgrounddrawable(statelistdrawable);
 
    android.widget.relativelayout.layoutparams rightpp = new android.widget.relativelayout.layoutparams(
        viewutil.dip2px(mcontext, 25), viewutil.dip2px(mcontext, 22));
    rightpp.addrule(relativelayout.align_parent_right);
    rightpp.addrule(relativelayout.center_vertical, relativelayout.true);
    rightpp.setmargins(0, 0, 20, 0);
    mrightview.setlayoutparams(rightpp);
    mrightview.setonclicklistener(new onclicklistener() {
 
      @override
      public void onclick(view v) {
        // todo auto-generated method stub
        viewflipper.setinanimation(slideleftin);
        viewflipper.setoutanimation(slideleftout);
        viewflipper.shownext();
        setnextviewitem();
      }
    });
    top.addview(mrightview);
  }
 
  /** 生成中间显示week */
  private void generateweekgirdview() {
    gridview gridview = new gridview(mcontext);
    linearlayout.layoutparams params = new linearlayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    gridview.setlayoutparams(params);
    gridview.setnumcolumns(7);// 设置每行列数
    gridview.setgravity(gravity.center_vertical);// 位置居中
    gridview.setverticalspacing(1);// 垂直间隔
    gridview.sethorizontalspacing(1);// 水平间隔
    gridview.setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4));
 
    int i = screenwidth / 7;
    int j = screenwidth - (i * 7);
    int x = j / 2;
    gridview.setpadding(x, 0, 0, 0);// 居中
    weekgridadapter weekadapter = new weekgridadapter(mcontext);
    gridview.setadapter(weekadapter);// 设置菜单adapter
    mmainlayout.addview(gridview);
  }
 
  /** 生成底部日历 */
  private void generateclaendargirdview() {
    calendar tempselected1 = calendar.getinstance(); // 临时
    calendar tempselected2 = calendar.getinstance(); // 临时
    calendar tempselected3 = calendar.getinstance(); // 临时
    tempselected1.settime(calstartdate.gettime());
    tempselected2.settime(calstartdate.gettime());
    tempselected3.settime(calstartdate.gettime());
 
    gview1 = new calendargridview(mcontext);
    tempselected1.add(calendar.month, -1);
    gadapter1 = new calendargridviewadapter(mcontext, tempselected1,
        markdates);
    gview1.setadapter(gadapter1);// 设置菜单adapter
    gview1.setid(callayoutid);
 
    gview2 = new calendargridview(mcontext);
    gadapter = new calendargridviewadapter(mcontext, tempselected2,
        markdates);
    gview2.setadapter(gadapter);// 设置菜单adapter
    gview2.setid(callayoutid);
 
    gview3 = new calendargridview(mcontext);
    tempselected3.add(calendar.month, 1);
    gadapter3 = new calendargridviewadapter(mcontext, tempselected3,
        markdates);
    gview3.setadapter(gadapter3);// 设置菜单adapter
    gview3.setid(callayoutid);
 
    gview2.setontouchlistener(this);
    gview1.setontouchlistener(this);
    gview3.setontouchlistener(this);
 
    if (viewflipper.getchildcount() != 0) {
      viewflipper.removeallviews();
    }
 
    viewflipper.addview(gview2);
    viewflipper.addview(gview3);
    viewflipper.addview(gview1);
 
    string title = calstartdate.get(calendar.year)
        + "年"
        + numberhelper.leftpad_tow_zero(calstartdate
            .get(calendar.month) + 1) + "月";
    mtitle.settext(title);
  }
 
  // 上一个月
  private void setprevviewitem() {
    imonthviewcurrentmonth--;// 当前选择月--
    // 如果当前月为负数的话显示上一年
    if (imonthviewcurrentmonth == -1) {
      imonthviewcurrentmonth = 11;
      imonthviewcurrentyear--;
    }
    calstartdate.set(calendar.day_of_month, 1); // 设置日为当月1日
    calstartdate.set(calendar.month, imonthviewcurrentmonth); // 设置月
    calstartdate.set(calendar.year, imonthviewcurrentyear); // 设置年
  }
 
  // 下一个月
  private void setnextviewitem() {
    imonthviewcurrentmonth++;
    if (imonthviewcurrentmonth == 12) {
      imonthviewcurrentmonth = 0;
      imonthviewcurrentyear++;
    }
    calstartdate.set(calendar.day_of_month, 1);
    calstartdate.set(calendar.month, imonthviewcurrentmonth);
    calstartdate.set(calendar.year, imonthviewcurrentyear);
  }
 
  // 根据改变的日期更新日历
  // 填充日历控件用
  private void updatestartdateformonth() {
    calstartdate.set(calendar.date, 1); // 设置成当月第一天
    imonthviewcurrentmonth = calstartdate.get(calendar.month);// 得到当前日历显示的月
    imonthviewcurrentyear = calstartdate.get(calendar.year);// 得到当前日历显示的年
 
    // 星期一是2 星期天是1 填充剩余天数
    int iday = 0;
    int ifirstdayofweek = calendar.monday;
    int istartday = ifirstdayofweek;
    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);
  }
 
  /**
   * 设置标注的日期
   * 
   * @param markdates
   */
  public void setmarkdates(list<date> markdates) {
    this.markdates.clear();
    this.markdates.addall(markdates);
    gadapter.notifydatasetchanged();
    gadapter1.notifydatasetchanged();
    gadapter3.notifydatasetchanged();
  }
 
  /**
   * 设置点击日历监听
   * 
   * @param listener
   */
  public void setoncalendarviewlistener(oncalendarviewlistener listener) {
    this.mlistener = listener;
  }
 
  @override
  public boolean ondown(motionevent e) {
    // todo auto-generated method stub
    return false;
  }
 
  @suppresslint("clickableviewaccessibility")
  @override
  public boolean ontouch(view v, motionevent event) {
    return mgesture.ontouchevent(event);
  }
 
  @override
  public boolean onfling(motionevent e1, motionevent e2, float velocityx,
      float velocityy) {
    // todo auto-generated method stub
    try {
      if (math.abs(e1.gety() - e2.gety()) > swipe_max_off_path)
        return false;
      // right to left swipe
      if (e1.getx() - e2.getx() > swipe_min_distance
          && math.abs(velocityx) > swipe_threshold_velocity) {
        viewflipper.setinanimation(slideleftin);
        viewflipper.setoutanimation(slideleftout);
        viewflipper.shownext();
        setnextviewitem();
        return true;
 
      } else if (e2.getx() - e1.getx() > swipe_min_distance
          && math.abs(velocityx) > swipe_threshold_velocity) {
        viewflipper.setinanimation(sliderightin);
        viewflipper.setoutanimation(sliderightout);
        viewflipper.showprevious();
        setprevviewitem();
        return true;
 
      }
    } catch (exception e) {
      // nothing
    }
    return false;
  }
 
  @override
  public void onlongpress(motionevent e) {
    // todo auto-generated method stub
 
  }
 
  @override
  public boolean onscroll(motionevent e1, motionevent e2, float distancex,
      float distancey) {
    // todo auto-generated method stub
    return false;
  }
 
  @override
  public void onshowpress(motionevent e) {
    // todo auto-generated method stub
 
  }
 
  @override
  public boolean onsingletapup(motionevent e) {
    // todo auto-generated method stub
    // 得到当前选中的是第几个单元格
    int pos = gview2.pointtoposition((int) e.getx(), (int) e.gety());
    linearlayout txtday = (linearlayout) gview2.findviewbyid(pos
        + default_id);
    if (txtday != null) {
      if (txtday.gettag() != null) {
        date date = (date) txtday.gettag();
        calselected.settime(date);
 
        gadapter.setselecteddate(calselected);
        gadapter.notifydatasetchanged();
 
        gadapter1.setselecteddate(calselected);
        gadapter1.notifydatasetchanged();
 
        gadapter3.setselecteddate(calselected);
        gadapter3.notifydatasetchanged();
        if (mlistener != null)
          mlistener.oncalendaritemclick(this, date);
      }
    }
    return false;
  }
 
  @override
  public void onanimationend(animation animation) {
    // todo auto-generated method stub
    generateclaendargirdview();
  }
 
  @override
  public void onanimationrepeat(animation animation) {
    // todo auto-generated method stub
 
  }
 
  @override
  public void onanimationstart(animation animation) {
    // todo auto-generated method stub
 
  }
 
}
 
/**
 * 显示week的布局adapter
 * 
 */
class weekgridadapter extends baseadapter {
 
  final string[] titles = new string[] { "日", "一", "二", "三", "四", "五", "六" };
  private context mcontext;
 
  public weekgridadapter(context context) {
    this.mcontext = context;
  }
 
  @override
  public int getcount() {
    return titles.length;
  }
 
  @override
  public object getitem(int position) {
    return titles[position];
  }
 
  @override
  public long getitemid(int position) {
    return position;
  }
 
  @override
  public view getview(int position, view convertview, viewgroup parent) {
    textview week = new textview(mcontext);
    android.view.viewgroup.layoutparams week_params = new layoutparams(
        android.view.viewgroup.layoutparams.match_parent,
        android.view.viewgroup.layoutparams.match_parent);
    week.setlayoutparams(week_params);
    week.setpadding(0, 0, 0, 0);
    week.setgravity(gravity.center);
    week.setfocusable(false);
    week.setbackgroundcolor(color.transparent);
 
    if (position == 6) { // 周六
      week.setbackgroundcolor(color.argb(0xff, 0x52, 0x9b, 0xd0));
      week.settextcolor(color.white);
    } else if (position == 0) { // 周日
      week.setbackgroundcolor(color.argb(0xff, 0xbc, 0x44, 0x45));
      week.settextcolor(color.white);
    } else {
      week.settextcolor(color.black);
    }
    week.settext(getitem(position) + "");
    return week;
  }
}
 
/**
 * 显示日期的adapter
 */
class calendargridviewadapter extends baseadapter {
 
  /** 日历item中默认id从0xff0000开始 */
  private final static int default_id = 0xff0000;
  private calendar calstartdate = calendar.getinstance();// 当前显示的日历
  private calendar calselected = calendar.getinstance(); // 选择的日历
 
  /** 标注的日期 */
  private list<date> markdates;
 
  private context mcontext;
 
  private calendar caltoday = calendar.getinstance(); // 今日
  private arraylist<java.util.date> titles;
 
  private arraylist<java.util.date> getdates() {
 
    updatestartdateformonth();
 
    arraylist<java.util.date> alarraylist = new arraylist<java.util.date>();
 
    for (int i = 1; i <= 42; i++) {
      alarraylist.add(calstartdate.gettime());
      calstartdate.add(calendar.day_of_month, 1);
    }
 
    return alarraylist;
  }
 
  // construct
  public calendargridviewadapter(context context, calendar cal, list<date> dates) {
    calstartdate = cal;
    this.mcontext = context;
    titles = getdates();
    this.markdates = dates;
  }
 
  public calendargridviewadapter(context context) {
    this.mcontext = context;
  }
 
  @override
  public int getcount() {
    return titles.size();
  }
 
  @override
  public object getitem(int position) {
    return titles.get(position);
  }
 
  @override
  public long getitemid(int position) {
    return position;
  }
 
  @suppresswarnings("deprecation")
  @override
  public view getview(int position, view convertview, viewgroup parent) {
    // 整个item
    linearlayout itemlayout = new linearlayout(mcontext);
    itemlayout.setid(position + default_id);
    itemlayout.setgravity(gravity.center);
    itemlayout.setorientation(1);
    itemlayout.setbackgroundcolor(color.white);
 
    date mydate = (date) getitem(position);
    itemlayout.settag(mydate);
    calendar calcalendar = calendar.getinstance();
    calcalendar.settime(mydate);
 
    // 显示日期day
    textview textday = new textview(mcontext);// 日期
    linearlayout.layoutparams text_params = new linearlayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    textday.setgravity(gravity.center_horizontal);
    int day = mydate.getdate(); // 日期
    textday.settext(string.valueof(day));
    textday.setid(position + default_id);
    itemlayout.addview(textday, text_params);
 
    // 显示公历
    textview chineseday = new textview(mcontext);
    linearlayout.layoutparams chinese_params = new linearlayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    chineseday.setgravity(gravity.center_horizontal);
    chineseday.settextsize(9);
    calendarutil calendarutil = new calendarutil(calcalendar);
    chineseday.settext(calendarutil.tostring());
    itemlayout.addview(chineseday, chinese_params);
 
    // 如果是当前日期则显示不同颜色
    if (equalsdate(caltoday.gettime(), mydate)) {
      itemlayout.setbackgroundcolor(color.argb(0xff, 0x6d, 0xd6, 0x97));
    }
 
    // 这里用于比对是不是比当前日期小,如果比当前日期小则显示浅灰色
    if (!calendarutil.compare(mydate, caltoday.gettime())) {
      itemlayout.setbackgroundcolor(color.argb(0xff, 0xee, 0xee, 0xee));
      textday.settextcolor(color.argb(0xff, 0xc0, 0xc0, 0xc0));
      chineseday.settextcolor(color.argb(0xff, 0xc0, 0xc0, 0xc0));
    } else {
      chineseday.settextcolor(color.argb(0xff, 0xc2, 0xa5, 0x3d));
      chineseday.settextcolor(color.argb(0xff, 0x60, 0x3b, 0x07));
      // 设置背景颜色
      if (equalsdate(calselected.gettime(), mydate)) {
        // 选择的
        itemlayout.setbackgroundcolor(color.argb(0xff, 0xdc, 0xe2, 0xff));
      } else {
        if (equalsdate(caltoday.gettime(), mydate)) {
          // 当前日期faedda
          itemlayout.setbackgroundcolor(color.argb(0xff, 0xfa, 0xed, 0xda));
        }
      }
    }
    /** 设置标注日期颜色 */
    if (markdates != null) {
      final simpledateformat format = new simpledateformat("yyyy-mm-dd", locale.china);
      for (date date : markdates) {
        if (format.format(mydate).equals(format.format(date))) {
          itemlayout.setbackgroundcolor(color.argb(0xff, 0xd3, 0x3a, 0x3a));
          break;
        }
      }
    }
    return itemlayout;
  }
 
  @override
  public void notifydatasetchanged() {
    super.notifydatasetchanged();
  }
 
  @suppresswarnings("deprecation")
  private boolean equalsdate(date date1, date date2) {
    if (date1.getyear() == date2.getyear()
        && date1.getmonth() == date2.getmonth()
        && date1.getdate() == date2.getdate()) {
      return true;
    } else {
      return false;
    }
 
  }
 
  // 根据改变的日期更新日历
  // 填充日历控件用
  private void updatestartdateformonth() {
    calstartdate.set(calendar.date, 1); // 设置成当月第一天
 
    // 星期一是2 星期天是1 填充剩余天数
    int iday = 0;
    int ifirstdayofweek = calendar.monday;
    int istartday = ifirstdayofweek;
    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);
    calstartdate.add(calendar.day_of_month, -1);// 周日第一位
  }
 
  public void setselecteddate(calendar cal) {
    calselected = cal;
  }
 
}
 
/**
 * 用于生成日历展示的gridview布局
 */
class calendargridview extends gridview {
 
  /**
   * 当前操作的上下文对象
   */
  private context mcontext;
 
  /**
   * calendargridview 构造器
   * 
   * @param context
   *      当前操作的上下文对象
   */
  public calendargridview(context context) {
    super(context);
    mcontext = context;
    initgirdview();
  }
 
  /**
   * 初始化gridview 控件的布局
   */
  private void initgirdview() {
    linearlayout.layoutparams params = new linearlayout.layoutparams(
        layoutparams.match_parent, layoutparams.wrap_content);
    setlayoutparams(params);
    setnumcolumns(7);// 设置每行列数
    setgravity(gravity.center_vertical);// 位置居中
    setverticalspacing(1);// 垂直间隔
    sethorizontalspacing(1);// 水平间隔
    setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4));
 
    int i = mcontext.getresources().getdisplaymetrics().widthpixels / 7;
    int j = mcontext.getresources().getdisplaymetrics().widthpixels
        - (i * 7);
    int x = j / 2;
    setpadding(x, 0, 0, 0);// 居中
  }
}
 
/**
 * 把公历时间处理成农历时间
 * 
 */
class calendarutil {
  /**
   * 用于保存中文的月份
   */
  private final static string chinese_number[] = { "一", "二", "三", "四", "五",
      "六", "七", "八", "九", "十", "十一", "腊" };
 
  /**
   * 用于保存展示周几使用
   */
  private final static string week_number[] = { "日", "一", "二", "三", "四", "五",
      "六" };
 
  private final static long[] lunar_info = new long[] { 0x04bd8, 0x04ae0,
      0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0,
      0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540,
      0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5,
      0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
      0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3,
      0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0,
      0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0,
      0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8,
      0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570,
      0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5,
      0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0,
      0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50,
      0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0,
      0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
      0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7,
      0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50,
      0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954,
      0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,
      0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0,
      0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0,
      0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20,
      0x0ada0 };
 
  /**
   * 转换为2012年11月22日格式
   */
  private static simpledateformat chinesedateformat = new simpledateformat(
      "yyyy年mm月dd日");
  /**
   * 转换为2012-11-22格式
   */
  private static simpledateformat simpledateformat = new simpledateformat(
      "yyyy-mm-dd");
 
  /**
   * 计算得到农历的年份
   */
  private int mluchyear;
  /**
   * 计算得到农历的月份
   */
  private int mluchmonth;
 
  /**
   * 计算得到农历的日期
   */
  private int mluchday;
 
  /**
   * 用于标识是事为闰年
   */
  private boolean isloap;
 
  /**
   * 用于记录当前处理的时间
   */
  private calendar mcurrencalendar;
 
  /**
   * 传回农历 year年的总天数
   *
   * @param year
   *      将要计算的年份
   * @return 返回传入年份的总天数
   */
  private static int yeardays(int year) {
    int i, sum = 348;
    for (i = 0x8000; i > 0x8; i >>= 1) {
      if ((lunar_info[year - 1900] & i) != 0)
        sum += 1;
    }
    return (sum + leapdays(year));
  }
 
  /**
   * 传回农历 year年闰月的天数
   *
   * @param year
   *      将要计算的年份
   * @return 返回 农历 year年闰月的天数
   */
  private static int leapdays(int year) {
    if (leapmonth(year) != 0) {
      if ((lunar_info[year - 1900] & 0x10000) != 0)
        return 30;
      else
        return 29;
    } else
      return 0;
  }
 
  /**
   * 传回农历 year年闰哪个月 1-12 , 没闰传回 0
   *
   * @param year
   *      将要计算的年份
   * @return 传回农历 year年闰哪个月 1-12 , 没闰传回 0
   */
  private static int leapmonth(int year) {
    return (int) (lunar_info[year - 1900] & 0xf);
  }
 
  /**
   * 传回农历 year年month月的总天数
   *
   * @param year
   *      将要计算的年份
   * @param month
   *      将要计算的月份
   * @return 传回农历 year年month月的总天数
   */
  private static int monthdays(int year, int month) {
    if ((lunar_info[year - 1900] & (0x10000 >> month)) == 0)
      return 29;
    else
      return 30;
  }
 
  /**
   * 传回农历 y年的生肖
   *
   * @return 传回农历 y年的生肖
   */
  public string animalsyear() {
    final string[] animals = new string[] { "鼠", "牛", "虎", "兔", "龙", "蛇",
        "马", "羊", "猴", "鸡", "狗", "猪" };
    return animals[(mluchyear - 4) % 12];
  }
 
  // ====== 传入 月日的offset 传回干支, 0=甲子
  private static string cyclicalm(int num) {
    final string[] gan = new string[] { "甲", "乙", "丙", "丁", "戊", "己", "庚",
        "辛", "壬", "癸" };
    final string[] zhi = new string[] { "子", "丑", "寅", "卯", "辰", "巳", "午",
        "未", "申", "酉", "戌", "亥" };
 
    return (gan[num % 10] + zhi[num % 12]);
  }
 
  // ====== 传入 offset 传回干支, 0=甲子
  public string cyclical() {
    int num = mluchyear - 1900 + 36;
    return (cyclicalm(num));
  }
 
  /**
   * 传出y年m月d日对应的农历. yearcyl3:农历年与1864的相差数 ? moncyl4:从1900年1月31日以来,闰月数
   * daycyl5:与1900年1月31日相差的天数,再加40 ?
   *
   * @param cal
   * @return
   */
  public calendarutil(calendar cal) {
    mcurrencalendar = cal;
    int leapmonth = 0;
    date basedate = null;
    try {
      basedate = chinesedateformat.parse("1900年1月31日");
    } catch (parseexception e) {
      e.printstacktrace(); // to change body of catch statement use
      // options | file templates.
    }
 
    // 求出和1900年1月31日相差的天数
    int offset = (int) ((cal.gettime().gettime() - basedate.gettime()) / 86400000l);
    // 用offset减去每农历年的天数
    // 计算当天是农历第几天
    // i最终结果是农历的年份
    // offset是当年的第几天
    int iyear, daysofyear = 0;
    for (iyear = 1900; iyear < 2050 && offset > 0; iyear++) {
      daysofyear = yeardays(iyear);
      offset -= daysofyear;
    }
    if (offset < 0) {
      offset += daysofyear;
      iyear--;
    }
    // 农历年份
    mluchyear = iyear;
 
    leapmonth = leapmonth(iyear); // 闰哪个月,1-12
    isloap = false;
 
    // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
    int imonth, daysofmonth = 0;
    for (imonth = 1; imonth < 13 && offset > 0; imonth++) {
      // 闰月
      if (leapmonth > 0 && imonth == (leapmonth + 1) && !isloap) {
        --imonth;
        isloap = true;
        daysofmonth = leapdays(mluchyear);
      } else
        daysofmonth = monthdays(mluchyear, imonth);
 
      offset -= daysofmonth;
      // 解除闰月
      if (isloap && imonth == (leapmonth + 1))
        isloap = false;
      if (!isloap) {
      }
    }
    // offset为0时,并且刚才计算的月份是闰月,要校正
    if (offset == 0 && leapmonth > 0 && imonth == leapmonth + 1) {
      if (isloap) {
        isloap = false;
      } else {
        isloap = true;
        --imonth;
      }
    }
    // offset小于0时,也要校正
    if (offset < 0) {
      offset += daysofmonth;
      --imonth;
 
    }
    mluchmonth = imonth;
    mluchday = offset + 1;
  }
 
  /**
   * 返化成中文格式
   *
   * @param day
   * @return
   */
  public static string getchinadaystring(int day) {
    string chineseten[] = { "初", "十", "廿", "卅" };
    int n = day % 10 == 0 ? 9 : day % 10 - 1;
    if (day > 30)
      return "";
    if (day == 10)
      return "初十";
    else
      return chineseten[day / 10] + chinese_number[n];
  }
 
  /**
   * 用于显示农历的初几这种格式
   *
   * @return 农历的日期
   */
  public string tostring() {
    string message = "";
    // int n = mluchday % 10 == 0 ? 9 : mluchday % 10 - 1;
    message = getchinacalendarmsg(mluchyear, mluchmonth, mluchday);
    if (stringutil.isnullorempty(message)) {
      string solarmsg = new solartermsutil(mcurrencalendar)
          .getsolartermsmsg();
      // 判断当前日期是否为节气
      if (!stringutil.isnullorempty(solarmsg)) {
        message = solarmsg;
      } else {
        /**
         * 判断当前日期是否为公历节日
         */
        string gremessage = new gregorianutil(mcurrencalendar)
            .getgremessage();
        if (!stringutil.isnullorempty(gremessage)) {
          message = gremessage;
        } else if (mluchday == 1) {
          message = chinese_number[mluchmonth - 1] + "月";
        } else {
          message = getchinadaystring(mluchday);
        }
 
      }
    }
    return message;
  }
 
  /**
   * 返回农历的年月日
   *
   * @return 农历的年月日格式
   */
  public string getday() {
    return (isloap ? "闰" : "") + chinese_number[mluchmonth - 1] + "月"
        + getchinadaystring(mluchday);
  }
 
  /**
   * 把calendar转化为当前年月日
   *
   * @param calendar
   *      calendar
   * @return 返回成转换好的 年月日格式
   */
  public static string getday(calendar calendar) {
    return simpledateformat.format(calendar.gettime());
  }
 
  /**
   * 用于比对二个日期的大小
   *
   * @param comparedate
   *      将要比对的时间
   * @param currentdate
   *      当前时间
   * @return true 表示大于当前时间 false 表示小于当前时间
   */
  public static boolean compare(date comparedate, date currentdate) {
    return chinesedateformat.format(comparedate).compareto(
        chinesedateformat.format(currentdate)) >= 0;
  }
 
  /**
   * 获取当前周几
   *
   * @param calendar
   * @return
   */
  public static string getweek(calendar calendar) {
    return "周" + week_number[calendar.get(calendar.day_of_week) - 1] + "";
  }
 
  /**
   * 将当前时间转换成要展示的形式
   *
   * @param calendar
   * @return
   */
  public static string getcurrentday(calendar calendar) {
    return getday(calendar) + " 农历" + new calendarutil(calendar).getday()
        + " " + getweek(calendar);
  }
 
  /**
   * 用于获取中国的传统节日
   *
   * @param month
   *      农历的月
   * @param day
   *      农历日
   * @return 中国传统节日
   */
  private string getchinacalendarmsg(int year, int month, int day) {
    string message = "";
    if (((month) == 1) && day == 1) {
      message = "春节";
    } else if (((month) == 1) && day == 15) {
      message = "元宵";
    } else if (((month) == 5) && day == 5) {
      message = "端午";
    } else if ((month == 7) && day == 7) {
      message = "七夕";
    } else if (((month) == 8) && day == 15) {
      message = "中秋";
    } else if ((month == 9) && day == 9) {
      message = "重阳";
    } else if ((month == 12) && day == 8) {
      message = "腊八";
    } else {
      if (month == 12) {
        if ((((monthdays(year, month) == 29) && day == 29))
            || ((((monthdays(year, month) == 30) && day == 30)))) {
          message = "除夕";
        }
      }
    }
    return message;
  }
}
 
/**
 * 字符串的处理类
 */
class stringutil {
  /**
   * 判断是否为null或空值
   *
   * @param str
   *      string
   * @return true or false
   */
  public static boolean isnullorempty(string str) {
    return str == null || str.trim().length() == 0;
  }
 
  /**
   * 判断str1和str2是否相同
   *
   * @param str1
   *      str1
   * @param str2
   *      str2
   * @return true or false
   */
  public static boolean equals(string str1, string str2) {
    return str1 == str2 || str1 != null && str1.equals(str2);
  }
 
  /**
   * 判断str1和str2是否相同(不区分大小写)
   *
   * @param str1
   *      str1
   * @param str2
   *      str2
   * @return true or false
   */
  public static boolean equalsignorecase(string str1, string str2) {
    return str1 != null && str1.equalsignorecase(str2);
  }
 
  /**
   * 判断字符串str1是否包含字符串str2
   *
   * @param str1
   *      源字符串
   * @param str2
   *      指定字符串
   * @return true源字符串包含指定字符串,false源字符串不包含指定字符串
   */
  public static boolean contains(string str1, string str2) {
    return str1 != null && str1.contains(str2);
  }
 
  /**
   * 判断字符串是否为空,为空则返回一个空值,不为空则返回原字符串
   *
   * @param str
   *      待判断字符串
   * @return 判断后的字符串
   */
  public static string getstring(string str) {
    return str == null ? "" : str;
  }
}
 
/**
 * 主要用于把公历日期处理成24节气
 */
class solartermsutil {
 
  /**
   * 计算得到公历的年份
   */
  private int gregorianyear;
 
  /**
   * 计算得到公历的月份
   */
  private int gregorianmonth;
 
  /**
   * 用于计算得到公历的日期
   */
  private int gregoriandate;
 
  private int chineseyear;
  private int chinesemonth;
  private int chinesedate;
 
  // 初始日,公历农历对应日期:
  // 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日
  private static int baseyear = 1901;
  private static int basemonth = 1;
  private static int basedate = 1;
  private static int baseindex = 0;
  private static int basechineseyear = 4598 - 1;
  private static int basechinesemonth = 11;
  private static int basechinesedate = 11;
  private static char[] daysingregorianmonth = { 31, 28, 31, 30, 31, 30, 31,
      31, 30, 31, 30, 31 };
 
  private int sectionalterm;
  private int principleterm;
 
  private static char[][] sectionaltermmap = {
      { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5,
          5, 5, 5, 4, 5, 5 },
      { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3,
          3, 4, 4, 3, 3, 3 },
      { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
          5, 5, 4, 5, 5, 5, 5 },
      { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4,
          4, 5, 4, 4, 4, 4, 5 },
      { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
          5, 5, 4, 5, 5, 5, 5 },
      { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5,
          5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 },
      { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
          7, 7, 6, 6, 6, 7, 7 },
      { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
          7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 },
      { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
          7, 7, 6, 7, 7, 7, 7 },
      { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8,
          8, 8, 7, 7, 8, 8, 8 },
      { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7,
          7, 7, 6, 6, 7, 7, 7 },
      { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
          7, 7, 6, 6, 6, 7, 7 } };
  private static char[][] sectionaltermyear = {
      { 13, 49, 85, 117, 149, 185, 201, 250, 250 },
      { 13, 45, 81, 117, 149, 185, 201, 250, 250 },
      { 13, 48, 84, 112, 148, 184, 200, 201, 250 },
      { 13, 45, 76, 108, 140, 172, 200, 201, 250 },
      { 13, 44, 72, 104, 132, 168, 200, 201, 250 },
      { 5, 33, 68, 96, 124, 152, 188, 200, 201 },
      { 29, 57, 85, 120, 148, 176, 200, 201, 250 },
      { 13, 48, 76, 104, 132, 168, 196, 200, 201 },
      { 25, 60, 88, 120, 148, 184, 200, 201, 250 },
      { 16, 44, 76, 108, 144, 172, 200, 201, 250 },
      { 28, 60, 92, 124, 160, 192, 200, 201, 250 },
      { 17, 53, 85, 124, 156, 188, 200, 201, 250 } };
  private static char[][] principletermmap = {
      { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20,
          20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20 },
      { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19,
          19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18 },
      { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21,
          20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20 },
      { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20,
          19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20 },
      { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21,
          20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21 },
      { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22,
          21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21 },
      { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23,
          22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23 },
      { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
          22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
      { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
          22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
      { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24,
          23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23 },
      { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23,
          22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22 },
      { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22,
          21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22 } };
  private static char[][] principletermyear = {
      { 13, 45, 81, 113, 149, 185, 201 },
      { 21, 57, 93, 125, 161, 193, 201 },
      { 21, 56, 88, 120, 152, 188, 200, 201 },
      { 21, 49, 81, 116, 144, 176, 200, 201 },
      { 17, 49, 77, 112, 140, 168, 200, 201 },
      { 28, 60, 88, 116, 148, 180, 200, 201 },
      { 25, 53, 84, 112, 144, 172, 200, 201 },
      { 29, 57, 89, 120, 148, 180, 200, 201 },
      { 17, 45, 73, 108, 140, 168, 200, 201 },
      { 28, 60, 92, 124, 160, 192, 200, 201 },
      { 16, 44, 80, 112, 148, 180, 200, 201 },
      { 17, 53, 88, 120, 156, 188, 200, 201 } };
 
  private static char[] chinesemonths = {
      // 农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数,
      // 前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。
      0x00, 0x04, 0xad, 0x08, 0x5a, 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64,
      0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08,
      0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94,
      0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02,
      0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56,
      0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05,
      0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec,
      0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a,
      0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52,
      0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02,
      0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a,
      0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09,
      0xb0, 0x39, 0x64, 0x05, 0x25, 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d,
      0x54, 0xad, 0x04, 0xda, 0x04, 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85,
      0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a,
      0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d,
      0x2a, 0x09, 0x56, 0x01, 0xad, 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1,
      0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54,
      0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51,
      0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52,
      0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d,
      0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45,
      0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda,
      0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a,
      0x96, 0x04, 0xad, 0xb0, 0xad, 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4,
      0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22,
      0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49,
      0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01,
      0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa,
      0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a,
      0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5,
      0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05,
      0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69,
      0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09,
      0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4,
      0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04,
      0x74, 0x05, 0xb0, 0x25, 0x54, 0x03 };
 
  /**
   * 用于保存24节气
   */
  private static string[] principletermnames = { "大寒", "雨水", "春分", "谷雨",
      "小满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至" };
  /**
   * 用于保存24节气
   */
  private static string[] sectionaltermnames = { "小寒", "立春", "惊蛰", "清明",
      "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪" };
 
  public solartermsutil(calendar calendar) {
    gregorianyear = calendar.get(calendar.year);
    gregorianmonth = calendar.get(calendar.month) + 1;
    gregoriandate = calendar.get(calendar.date);
    computechinesefields();
    computesolarterms();
  }
 
  public int computechinesefields() {
    if (gregorianyear < 1901 || gregorianyear > 2100)
      return 1;
    int startyear = baseyear;
    int startmonth = basemonth;
    int startdate = basedate;
    chineseyear = basechineseyear;
    chinesemonth = basechinesemonth;
    chinesedate = basechinesedate;
    // 第二个对应日,用以提高计算效率
    // 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日
    if (gregorianyear >= 2000) {
      startyear = baseyear + 99;
      startmonth = 1;
      startdate = 1;
      chineseyear = basechineseyear + 99;
      chinesemonth = 11;
      chinesedate = 25;
    }
    int daysdiff = 0;
    for (int i = startyear; i < gregorianyear; i++) {
      daysdiff += 365;
      if (isgregorianleapyear(i))
        daysdiff += 1; // leap year
    }
    for (int i = startmonth; i < gregorianmonth; i++) {
      daysdiff += daysingregorianmonth(gregorianyear, i);
    }
    daysdiff += gregoriandate - startdate;
 
    chinesedate += daysdiff;
    int lastdate = daysinchinesemonth(chineseyear, chinesemonth);
    int nextmonth = nextchinesemonth(chineseyear, chinesemonth);
    while (chinesedate > lastdate) {
      if (math.abs(nextmonth) < math.abs(chinesemonth))
        chineseyear++;
      chinesemonth = nextmonth;
      chinesedate -= lastdate;
      lastdate = daysinchinesemonth(chineseyear, chinesemonth);
      nextmonth = nextchinesemonth(chineseyear, chinesemonth);
    }
    return 0;
  }
 
  public int computesolarterms() {
    if (gregorianyear < 1901 || gregorianyear > 2100)
      return 1;
    sectionalterm = sectionalterm(gregorianyear, gregorianmonth);
    principleterm = principleterm(gregorianyear, gregorianmonth);
    return 0;
  }
 
  public static int sectionalterm(int y, int m) {
    if (y < 1901 || y > 2100)
      return 0;
    int index = 0;
    int ry = y - baseyear + 1;
    while (ry >= sectionaltermyear[m - 1][index])
      index++;
    int term = sectionaltermmap[m - 1][4 * index + ry % 4];
    if ((ry == 121) && (m == 4))
      term = 5;
    if ((ry == 132) && (m == 4))
      term = 5;
    if ((ry == 194) && (m == 6))
      term = 6;
    return term;
  }
 
  public static int principleterm(int y, int m) {
    if (y < 1901 || y > 2100)
      return 0;
    int index = 0;
    int ry = y - baseyear + 1;
    while (ry >= principletermyear[m - 1][index])
      index++;
    int term = principletermmap[m - 1][4 * index + ry % 4];
    if ((ry == 171) && (m == 3))
      term = 21;
    if ((ry == 181) && (m == 5))
      term = 21;
    return term;
  }
 
  /**
   * 用于判断输入的年份是否为闰年
   * 
   * @param year
   *      输入的年份
   * @return true 表示闰年
   */
  public static boolean isgregorianleapyear(int year) {
    boolean isleap = false;
    if (year % 4 == 0)
      isleap = true;
    if (year % 100 == 0)
      isleap = false;
    if (year % 400 == 0)
      isleap = true;
    return isleap;
  }
 
  public static int daysingregorianmonth(int y, int m) {
    int d = daysingregorianmonth[m - 1];
    if (m == 2 && isgregorianleapyear(y))
      d++; // 公历闰年二月多一天
    return d;
  }
 
  public static int daysinchinesemonth(int y, int m) {
    // 注意:闰月 m < 0
    int index = y - basechineseyear + baseindex;
    int v = 0;
    int l = 0;
    int d = 30;
    if (1 <= m && m <= 8) {
      v = chinesemonths[2 * index];
      l = m - 1;
      if (((v >> l) & 0x01) == 1)
        d = 29;
    } else if (9 <= m && m <= 12) {
      v = chinesemonths[2 * index + 1];
      l = m - 9;
      if (((v >> l) & 0x01) == 1)
        d = 29;
    } else {
      v = chinesemonths[2 * index + 1];
      v = (v >> 4) & 0x0f;
      if (v != math.abs(m)) {
        d = 0;
      } else {
        d = 29;
        for (int i = 0; i < bigleapmonthyears.length; i++) {
          if (bigleapmonthyears[i] == index) {
            d = 30;
            break;
          }
        }
      }
    }
    return d;
  }
 
  public static int nextchinesemonth(int y, int m) {
    int n = math.abs(m) + 1;
    if (m > 0) {
      int index = y - basechineseyear + baseindex;
      int v = chinesemonths[2 * index + 1];
      v = (v >> 4) & 0x0f;
      if (v == m)
        n = -m;
    }
    if (n == 13)
      n = 1;
    return n;
  }
 
  // 大闰月的闰年年份
  private static int[] bigleapmonthyears = { 6, 14, 19, 25, 33, 36, 38, 41,
      44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193 };
 
  /**
   * 用于获取24节气的值
   * 
   * @return 24节气的值
   */
  public string getsolartermsmsg() {
    string str = "";
    string gm = string.valueof(gregorianmonth);
    if (gm.length() == 1)
      gm = ' ' + gm;
    string cm = string.valueof(math.abs(chinesemonth));
    if (cm.length() == 1)
      cm = ' ' + cm;
    string gd = string.valueof(gregoriandate);
    if (gd.length() == 1)
      gd = ' ' + gd;
    string cd = string.valueof(chinesedate);
    if (cd.length() == 1)
      cd = ' ' + cd;
    if (gregoriandate == sectionalterm) {
      str = " " + sectionaltermnames[gregorianmonth - 1];
    } else if (gregoriandate == principleterm) {
      str = " " + principletermnames[gregorianmonth - 1];
    }
    return str;
  }
}
 
/**
 * 对公历日期的处理类
 */
class gregorianutil {
  private final static string[][] gre_festvial = {
      // 一月
      { "元旦", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 二月
      { "", "", "", "", "", "", "", "", "", "", "", "", "", "情人", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 三月
      { "", "", "", "", "", "", "", "妇女", "", "", "", "植树", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "" },
      // 四月
      { "愚人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 五月
      { "劳动", "", "", "青年", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "" },
      // 六月
      { "儿童", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 七月
      { "建党", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 八月
      { "建军", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 九月
      { "", "", "", "", "", "", "", "", "", "教师", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 十月
      { "国庆", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 十一月
      { "", "", "", "", "", "", "", "", "", "", "光棍", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
      // 十二月
      { "艾滋病", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "圣诞", "", "", "", "",
          "", "" }, };
  private int mmonth;
  private int mday;
 
  public gregorianutil(calendar calendar) {
    mmonth = calendar.get(calendar.month);
    mday = calendar.get(calendar.date);
  }
 
  public string getgremessage() {
    return gre_festvial[mmonth][mday - 1];
  }
}
 
class numberhelper {
  public static string leftpad_tow_zero(int str) {
    java.text.decimalformat format = new java.text.decimalformat("00");
    return format.format(str);
  }
}
/*****************将代码拷贝到一个文件中(end)***********************/
 
//辅助类
package cc.util.android.view;
 
import android.content.context;
import android.content.res.resources;
import android.view.view;
import android.view.viewgroup;
import android.view.viewgroup.marginlayoutparams;
import android.widget.abslistview;
import android.widget.gridview;
import android.widget.listadapter;
import android.widget.listview;
 
/**
 * @author wangcccong
 * @version 1.140122
 * create at:2014-02-26
 */
public class viewutil {
 
  /**
   * 获取屏幕的宽度
   * @param context
   * @return
   */
  public int getscreenwidth(context context) {
    resources res = context.getresources();
    return res.getdisplaymetrics().widthpixels;
  }
   
  /**
   * 获取屏幕高度
   * @param context
   * @return
   */
  public int getscreenheight(context context) {
    resources res = context.getresources();
    return res.getdisplaymetrics().heightpixels;
  }
   
  /**
   * 描述:根据分辨率获得字体大小.
   *
   * @param screenwidth the screen width
   * @param screenheight the screen height
   * @param textsize the text size
   * @return the int
   */
  public static int resizetextsize(int screenwidth,int screenheight,int textsize){
    float ratio = 1;
    try {
      float ratiowidth = (float)screenwidth / 480; 
      float ratioheight = (float)screenheight / 800; 
      ratio = math.min(ratiowidth, ratioheight); 
    } catch (exception e) {
    }
    return math.round(textsize * ratio);
  }
   
  /**
   * 
   * 描述:dip转换为px
   * @param context
   * @param dipvalue
   * @return
   * @throws 
   */
  public static int dip2px(context context, float dipvalue) {
    final float scale = context.getresources().getdisplaymetrics().density;
    return math.round(dipvalue * scale);
  }
 
  /**
   * 
   * 描述:px转换为dip
   * @param context
   * @param pxvalue
   * @return
   * @throws 
   */
  public static int px2dip(context context, float pxvalue) {
    final float scale = context.getresources().getdisplaymetrics().density;
    return math.round(pxvalue / scale);
  }
   
  /**
   * 
   * 描述:px转换为sp
   * @param context
   * @param pxvalue
   * @return
   * @throws 
   */
  public static int px2sp(context context, float pxvalue) {
    final float scale = context.getresources().getdisplaymetrics().scaleddensity;
    return math.round(pxvalue / scale);
  }
   
  /**
   * 
   * 描述:sp转换为px
   * @param context
   * @param spvalue
   * @return
   * @throws 
   */
  public static int sp2px(context context, float spvalue) {
    final float scale = context.getresources().getdisplaymetrics().scaleddensity;
    return math.round(spvalue * scale);
  }
}
 
//使用方法
//在xml中添加控件
<cc.util.android.view.calendarview 
      android:id="@+id/calendar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/white"/>
//在代码中
calendarview calendarview = (calendarview) findviewbyid(r.id.calendar);
    //设置标注日期
    list<date> markdates = new arraylist<date>();
    markdates.add(new date());
    calendarview.setmarkdates(markdates);
 
    //设置点击操作
    calendarview.setoncalendarviewlistener(new oncalendarviewlistener() {
       
      @override
      public void oncalendaritemclick(calendarview view, date date) {
        // todo auto-generated method stub
        final simpledateformat format = new simpledateformat("yyyy年mm月dd日", locale.china);
        toast.maketext(mainactivity.this, format.format(date), toast.length_short).show();
      }
    });

所需图片:

Android实现自定义日历

Android实现自定义日历

Android实现自定义日历

Android实现自定义日历

Android实现自定义日历

以上所述就是本文的全部内容了,希望大家能够喜欢。