zoukankan      html  css  js  c++  java
  • 【无私分享】干货!!!一个炫酷的自定义日历控件,摆脱日历时间选择烦恼,纯福利~

    最近公司项目中有一个按日期查看信息的功能,楼主本想用之前用的wheelView将就使用的,不过产品经理有个新要求,就是点击按钮弹出的日期选择对话框必须显示农历节假日,周几什么的。这可就难为人了,倘若使用之前的滚动时间选择器,无疑是难以实现的,楼主辗转反侧,冥思苦想,却不得正果。

    对于楼主之前的wheelView写的滚动时间选择器,大家可以看看,分为了4种方式,还有仿QQ的发送消息哦:http://www.cnblogs.com/liushilin/p/5749481.html

    好吧,去网上下了几个OA系统一用就有了idea,突然想到手机自带的日历~~,oh,year,日历就有这功能,瞧瞧,我靠,这个东西,咋做。

    仔细一瞧,似乎用GridView可以实现,额,二话不说就开干。折腾了半天都没弄好,而且界面贼丑,并且特别是国历和公历上面如何一一对应呢?

    遇上楼主上google科普了一番,发现网上自定义日历不少,可是没有楼主想要的,好不容易找到一个功能齐全,可惜代码调了半天也用不起,好吧,只能一步一个脚印慢慢做。

    终于功夫不负有心人,最终楼主还是弄出来一个雏形。

    额,对,基本实现了日历功能,并能自动定位当前日期以及本月和非本月日期显示的不同,而且支持左右滑动哦~~

    额,有图有真相。

    最后,楼主把Demo分离了出来,供大家分享参阅。

    view包下几个东西。

    1)CalendarGridView.java

     1 package com.example.nanchen.mydateviewdemo.view;
     2 
     3 import android.content.Context;
     4 import android.graphics.Color;
     5 import android.view.Gravity;
     6 import android.widget.GridView;
     7 import android.widget.LinearLayout;
     8 
     9 /**
    10  *
    11  * 用于生成日历展示的GridView布局
    12  *
    13  * @author nanchen
    14  * @date 16-8-10 上午11:35
    15  */
    16 public class CalendarGridView extends GridView {
    17     /**
    18      * 当前操作的上下文对象
    19      */
    20     private Context mContext;
    21 
    22     /**
    23      * CalendarGridView 构造器
    24      *
    25      * @param context
    26      *            当前操作的上下文对象
    27      */
    28     public CalendarGridView(Context context) {
    29         super(context);
    30         mContext = context;
    31         initGirdView();
    32     }
    33 
    34     /**
    35      * 初始化gridView 控件的布局
    36      */
    37     private void initGirdView() {
    38         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    39                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    40         setLayoutParams(params);
    41         setNumColumns(7);// 设置每行列数
    42         setGravity(Gravity.CENTER_VERTICAL);// 位置居中
    43         setVerticalSpacing(1);// 垂直间隔
    44         setHorizontalSpacing(1);// 水平间隔
    45         setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));
    46 
    47         int i = mContext.getResources().getDisplayMetrics().widthPixels / 7;
    48         int j = mContext.getResources().getDisplayMetrics().widthPixels
    49                 - (i * 7);
    50         int x = j / 2;
    51         setPadding(x, 0, 0, 0);// 居中
    52     }
    53 }

    2)CalendarGridViewAdapter,java

      1 package com.example.nanchen.mydateviewdemo.view;
      2 
      3 import android.content.Context;
      4 import android.graphics.Color;
      5 import android.util.Log;
      6 import android.view.Gravity;
      7 import android.view.View;
      8 import android.view.ViewGroup;
      9 import android.view.ViewGroup.LayoutParams;
     10 import android.widget.BaseAdapter;
     11 import android.widget.LinearLayout;
     12 import android.widget.TextView;
     13 
     14 import com.example.nanchen.mydateviewdemo.R;
     15 
     16 import java.text.SimpleDateFormat;
     17 import java.util.ArrayList;
     18 import java.util.Calendar;
     19 import java.util.Date;
     20 import java.util.List;
     21 import java.util.Locale;
     22 
     23 /**
     24  * @author nanchen
     25  * @date 16-8-10 上午11:35
     26  */
     27 public class CalendarGridViewAdapter extends BaseAdapter {
     28     /** 日历item中默认id从0xff0000开始 */
     29     private final static int DEFAULT_ID = 0xff0000;
     30     private Calendar calStartDate = Calendar.getInstance();// 当前显示的日历
     31     private Calendar calSelected = Calendar.getInstance(); // 选择的日历
     32 
     33     /** 标注的日期 */
     34     private List<Date> markDates;
     35 
     36     private Context mContext;
     37 
     38     private Calendar calToday = Calendar.getInstance(); // 今日
     39     private ArrayList<Date> titles;
     40 
     41     private ArrayList<java.util.Date> getDates() {
     42 
     43         UpdateStartDateForMonth();
     44 
     45         ArrayList<java.util.Date> alArrayList = new ArrayList<java.util.Date>();
     46 
     47         for (int i = 1; i <= 42; i++) {
     48             alArrayList.add(calStartDate.getTime());
     49             calStartDate.add(Calendar.DAY_OF_MONTH, 1);
     50         }
     51 
     52         return alArrayList;
     53     }
     54 
     55     // construct
     56     public CalendarGridViewAdapter(Context context, Calendar cal, List<Date> dates) {
     57         calStartDate = cal;
     58         this.mContext = context;
     59         titles = getDates();
     60         this.markDates = dates;
     61     }
     62 
     63     public CalendarGridViewAdapter(Context context) {
     64         this.mContext = context;
     65     }
     66 
     67     @Override
     68     public int getCount() {
     69         return titles.size();
     70     }
     71 
     72     @Override
     73     public Object getItem(int position) {
     74         return titles.get(position);
     75     }
     76 
     77     @Override
     78     public long getItemId(int position) {
     79         return position;
     80     }
     81 
     82     @SuppressWarnings("deprecation")
     83     @Override
     84     public View getView(int position, View convertView, ViewGroup parent) {
     85         // 整个Item
     86         LinearLayout itemLayout = new LinearLayout(mContext);
     87         itemLayout.setId(position + DEFAULT_ID);
     88         itemLayout.setGravity(Gravity.CENTER);
     89         itemLayout.setOrientation(1);
     90         itemLayout.setBackgroundColor(Color.WHITE);
     91 
     92         Date myDate = (Date) getItem(position);
     93         itemLayout.setTag(myDate);
     94         Calendar calCalendar = Calendar.getInstance();
     95         calCalendar.setTime(myDate);
     96 
     97         // 显示日期day
     98         TextView textDay = new TextView(mContext);// 日期
     99         LinearLayout.LayoutParams text_params = new LinearLayout.LayoutParams(
    100                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    101         textDay.setGravity(Gravity.CENTER_HORIZONTAL);
    102         int day = myDate.getDate(); // 日期
    103         textDay.setTextSize(15);
    104         textDay.setText(String.valueOf(day));
    105         textDay.setId(position + DEFAULT_ID);
    106         itemLayout.addView(textDay, text_params);
    107 
    108         // 显示农历
    109         TextView chineseDay = new TextView(mContext);
    110         LinearLayout.LayoutParams chinese_params = new LinearLayout.LayoutParams(
    111                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    112         chineseDay.setGravity(Gravity.CENTER_HORIZONTAL);
    113         chineseDay.setTextSize(12);
    114         CalendarUtil calendarUtil = new CalendarUtil(calCalendar);
    115         chineseDay.setText(calendarUtil.toString());
    116         itemLayout.addView(chineseDay, chinese_params);//把农历添加在公历下面
    117 
    118         SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
    119         Log.e("flag",equalsDate(calToday.getTime(),myDate)+sdf.format(calToday.getTime()));
    120         // 如果是当前日期则显示不同颜色
    121         if (equalsDate(calToday.getTime(), myDate)) {//假定当前是8月10日
    122             itemLayout.setBackgroundColor(mContext.getResources().getColor(R.color.date_today_text_color));
    123         }
    124 
    125 //        Log.e("tag",equalsDate(myDate,calToday.getTime())+sdf.format(myDate));
    126 
    127         Log.e("tag",myDate.getMonth()+"---"+sdf.format(myDate));
    128         Log.e("tag",calToday.getTime().getMonth()+"====="+sdf.format(calToday.getTime()));
    129         if (equalsMonth(myDate,calStartDate.getTime())){
    130             textDay.setTextColor(mContext.getResources().getColor(R.color.date_text_color));
    131             chineseDay.setTextColor(mContext.getResources().getColor(R.color.date_text_color));
    132         }else{
    133             textDay.setTextColor(mContext.getResources().getColor(R.color.date_pre_color));
    134             chineseDay.setTextColor(mContext.getResources().getColor(R.color.date_pre_color));
    135         }
    136 
    137 
    138 
    139 
    140 
    141 
    164         /** 设置标注日期颜色 */
    165         if (markDates != null) {
    166             final SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
    167             for (Date date : markDates) {
    168                 if (format.format(myDate).equals(format.format(date))) {
    169 //                    itemLayout.setBackgroundColor(mContext.getResources().getColor(R.color.date_select_color));
    170                     break;
    171                 }
    172             }
    173         }
    174         return itemLayout;
    175     }
    176 
    177     @Override
    178     public void notifyDataSetChanged() {
    179         super.notifyDataSetChanged();
    180     }
    181 
    182     @SuppressWarnings("deprecation")
    183     private Boolean equalsDate(Date date1, Date date2) {
    184         if (date1.getYear() == date2.getYear()
    185                 && date1.getMonth() == date2.getMonth()
    186                 && date1.getDate() == date2.getDate()) {
    187             return true;
    188         } else {
    189             return false;
    190         }
    191     }
    192     @SuppressWarnings("deprecation")
    193     private boolean equalsMonth(Date date1,Date date2){
    194         if (date1.getMonth() == date2.getMonth()-1){
    195             return true;
    196         }
    197         return false;
    198     }
    199 
    200     // 根据改变的日期更新日历
    201     // 填充日历控件用
    202     private void UpdateStartDateForMonth() {
    203         calStartDate.set(Calendar.DATE, 1); // 设置成当月第一天
    204 
    205         // 星期一是2 星期天是1 填充剩余天数
    206         int iDay = 0;
    207         int iFirstDayOfWeek = Calendar.MONDAY;
    208         int iStartDay = iFirstDayOfWeek;
    209         if (iStartDay == Calendar.MONDAY) {
    210             iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
    211             if (iDay < 0)
    212                 iDay = 6;
    213         }
    214         if (iStartDay == Calendar.SUNDAY) {
    215             iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
    216             if (iDay < 0)
    217                 iDay = 6;
    218         }
    219         calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
    220         calStartDate.add(Calendar.DAY_OF_MONTH, -1);// 周日第一位
    221     }
    222 
    223     public void setSelectedDate(Calendar cal) {
    224         calSelected = cal;
    225     }
    226 
    227 }

    3)

    CalendarUtil
      1 package com.example.nanchen.mydateviewdemo.view;
      2 
      3 import java.text.ParseException;
      4 import java.text.SimpleDateFormat;
      5 import java.util.Calendar;
      6 import java.util.Date;
      7 
      8 /**
      9  * @author nanchen
     10  * @date 16-8-10 上午11:36
     11  */
     12 public class CalendarUtil {
     13     /**
     14      * 用于保存中文的月份
     15      */
     16     private final static String CHINESE_NUMBER[] = { "一", "二", "三", "四", "五",
     17             "六", "七", "八", "九", "十", "十一", "腊" };
     18 
     19     /**
     20      * 用于保存展示周几使用
     21      */
     22     private final static String WEEK_NUMBER[] = { "日", "一", "二", "三", "四", "五",
     23             "六" };
     24 
     25     private final static long[] LUNAR_INFO = new long[] { 0x04bd8, 0x04ae0,
     26             0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0,
     27             0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540,
     28             0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5,
     29             0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
     30             0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3,
     31             0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0,
     32             0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0,
     33             0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8,
     34             0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570,
     35             0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5,
     36             0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0,
     37             0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50,
     38             0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0,
     39             0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
     40             0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7,
     41             0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50,
     42             0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954,
     43             0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,
     44             0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0,
     45             0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0,
     46             0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20,
     47             0x0ada0 };
     48 
     49     /**
     50      * 转换为2012年11月22日格式
     51      */
     52     private static SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
     53             "yyyy年MM月dd日");
     54     /**
     55      * 转换为2012-11-22格式
     56      */
     57     private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
     58             "yyyy-MM-dd");
     59 
     60     /**
     61      * 计算得到农历的年份
     62      */
     63     private int mLuchYear;
     64     /**
     65      * 计算得到农历的月份
     66      */
     67     private int mLuchMonth;
     68 
     69     /**
     70      * 计算得到农历的日期
     71      */
     72     private int mLuchDay;
     73 
     74     /**
     75      * 用于标识是事为闰年
     76      */
     77     private boolean isLoap;
     78 
     79     /**
     80      * 用于记录当前处理的时间
     81      */
     82     private Calendar mCurrenCalendar;
     83 
     84     /**
     85      * 传回农历 year年的总天数
     86      *
     87      * @param year
     88      *            将要计算的年份
     89      * @return 返回传入年份的总天数
     90      */
     91     private static int yearDays(int year) {
     92         int i, sum = 348;
     93         for (i = 0x8000; i > 0x8; i >>= 1) {
     94             if ((LUNAR_INFO[year - 1900] & i) != 0)
     95                 sum += 1;
     96         }
     97         return (sum + leapDays(year));
     98     }
     99 
    100     /**
    101      * 传回农历 year年闰月的天数
    102      *
    103      * @param year
    104      *            将要计算的年份
    105      * @return 返回 农历 year年闰月的天数
    106      */
    107     private static int leapDays(int year) {
    108         if (leapMonth(year) != 0) {
    109             if ((LUNAR_INFO[year - 1900] & 0x10000) != 0)
    110                 return 30;
    111             else
    112                 return 29;
    113         } else
    114             return 0;
    115     }
    116 
    117     /**
    118      * 传回农历 year年闰哪个月 1-12 , 没闰传回 0
    119      *
    120      * @param year
    121      *            将要计算的年份
    122      * @return 传回农历 year年闰哪个月 1-12 , 没闰传回 0
    123      */
    124     private static int leapMonth(int year) {
    125         return (int) (LUNAR_INFO[year - 1900] & 0xf);
    126     }
    127 
    128     /**
    129      * 传回农历 year年month月的总天数
    130      *
    131      * @param year
    132      *            将要计算的年份
    133      * @param month
    134      *            将要计算的月份
    135      * @return 传回农历 year年month月的总天数
    136      */
    137     private static int monthDays(int year, int month) {
    138         if ((LUNAR_INFO[year - 1900] & (0x10000 >> month)) == 0)
    139             return 29;
    140         else
    141             return 30;
    142     }
    143 
    144     /**
    145      * 传回农历 y年的生肖
    146      *
    147      * @return 传回农历 y年的生肖
    148      */
    149     public String animalsYear() {
    150         final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇",
    151                 "马", "羊", "猴", "鸡", "狗", "猪" };
    152         return Animals[(mLuchYear - 4) % 12];
    153     }
    154 
    155     // ====== 传入 月日的offset 传回干支, 0=甲子
    156     private static String cyclicalm(int num) {
    157         final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚",
    158                 "辛", "壬", "癸" };
    159         final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午",
    160                 "未", "申", "酉", "戌", "亥" };
    161 
    162         return (Gan[num % 10] + Zhi[num % 12]);
    163     }
    164 
    165     // ====== 传入 offset 传回干支, 0=甲子
    166     public String cyclical() {
    167         int num = mLuchYear - 1900 + 36;
    168         return (cyclicalm(num));
    169     }
    170 
    171     /**
    172      * 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数
    173      * dayCyl5:与1900年1月31日相差的天数,再加40 ?
    174      *
    175      * @param cal
    176      * @return
    177      */
    178     public CalendarUtil(Calendar cal) {
    179         mCurrenCalendar = cal;
    180         int leapMonth = 0;
    181         Date baseDate = null;
    182         try {
    183             baseDate = chineseDateFormat.parse("1900年1月31日");
    184         } catch (ParseException e) {
    185             e.printStackTrace(); // To change body of catch statement use
    186             // Options | File Templates.
    187         }
    188 
    189         // 求出和1900年1月31日相差的天数
    190         int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
    191         // 用offset减去每农历年的天数
    192         // 计算当天是农历第几天
    193         // i最终结果是农历的年份
    194         // offset是当年的第几天
    195         int iYear, daysOfYear = 0;
    196         for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
    197             daysOfYear = yearDays(iYear);
    198             offset -= daysOfYear;
    199         }
    200         if (offset < 0) {
    201             offset += daysOfYear;
    202             iYear--;
    203         }
    204         // 农历年份
    205         mLuchYear = iYear;
    206 
    207         leapMonth = leapMonth(iYear); // 闰哪个月,1-12
    208         isLoap = false;
    209 
    210         // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
    211         int iMonth, daysOfMonth = 0;
    212         for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
    213             // 闰月
    214             if (leapMonth > 0 && iMonth == (leapMonth + 1) && !isLoap) {
    215                 --iMonth;
    216                 isLoap = true;
    217                 daysOfMonth = leapDays(mLuchYear);
    218             } else
    219                 daysOfMonth = monthDays(mLuchYear, iMonth);
    220 
    221             offset -= daysOfMonth;
    222             // 解除闰月
    223             if (isLoap && iMonth == (leapMonth + 1))
    224                 isLoap = false;
    225             if (!isLoap) {
    226             }
    227         }
    228         // offset为0时,并且刚才计算的月份是闰月,要校正
    229         if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
    230             if (isLoap) {
    231                 isLoap = false;
    232             } else {
    233                 isLoap = true;
    234                 --iMonth;
    235             }
    236         }
    237         // offset小于0时,也要校正
    238         if (offset < 0) {
    239             offset += daysOfMonth;
    240             --iMonth;
    241 
    242         }
    243         mLuchMonth = iMonth;
    244         mLuchDay = offset + 1;
    245     }
    246 
    247     /**
    248      * 返化成中文格式
    249      *
    250      * @param day
    251      * @return
    252      */
    253     public static String getChinaDayString(int day) {
    254         String chineseTen[] = { "初", "十", "廿", "卅" };
    255         int n = day % 10 == 0 ? 9 : day % 10 - 1;
    256         if (day > 30)
    257             return "";
    258         if (day == 10)
    259             return "初十";
    260         else
    261             return chineseTen[day / 10] + CHINESE_NUMBER[n];
    262     }
    263 
    264     /**
    265      * 用于显示农历的初几这种格式
    266      *
    267      * @return 农历的日期
    268      */
    269     public String toString() {
    270         String message = "";
    271         // int n = mLuchDay % 10 == 0 ? 9 : mLuchDay % 10 - 1;
    272         message = getChinaCalendarMsg(mLuchYear, mLuchMonth, mLuchDay);
    273         if (StringUtil.isNullOrEmpty(message)) {
    274             String solarMsg = new SolarTermsUtil(mCurrenCalendar)
    275                     .getSolartermsMsg();
    276             // 判断当前日期是否为节气
    277             if (!StringUtil.isNullOrEmpty(solarMsg)) {
    278                 message = solarMsg;
    279             } else {
    280                 /**
    281                  * 判断当前日期是否为公历节日
    282                  */
    283                 String gremessage = new GregorianUtil(mCurrenCalendar)
    284                         .getGremessage();
    285                 if (!StringUtil.isNullOrEmpty(gremessage)) {
    286                     message = gremessage;
    287                 } else if (mLuchDay == 1) {
    288                     message = CHINESE_NUMBER[mLuchMonth - 1] + "月";
    289                 } else {
    290                     message = getChinaDayString(mLuchDay);
    291                 }
    292 
    293             }
    294         }
    295         return message;
    296     }
    297 
    298     /**
    299      * 返回农历的年月日
    300      *
    301      * @return 农历的年月日格式
    302      */
    303     public String getDay() {
    304         return (isLoap ? "闰" : "") + CHINESE_NUMBER[mLuchMonth - 1] + "月"
    305                 + getChinaDayString(mLuchDay);
    306     }
    307 
    308     /**
    309      * 把calendar转化为当前年月日
    310      *
    311      * @param calendar
    312      *            Calendar
    313      * @return 返回成转换好的 年月日格式
    314      */
    315     public static String getDay(Calendar calendar) {
    316         return simpleDateFormat.format(calendar.getTime());
    317     }
    318 
    319     /**
    320      * 用于比对二个日期的大小
    321      *
    322      * @param compareDate
    323      *            将要比对的时间
    324      * @param currentDate
    325      *            当前时间
    326      * @return true 表示大于当前时间 false 表示小于当前时间
    327      */
    328     public static boolean compare(Date compareDate, Date currentDate) {
    329         return chineseDateFormat.format(compareDate).compareTo(
    330                 chineseDateFormat.format(currentDate)) >= 0;
    331     }
    332 
    333     /**
    334      * 获取当前周几
    335      *
    336      * @param calendar
    337      * @return
    338      */
    339     public static String getWeek(Calendar calendar) {
    340         return "周" + WEEK_NUMBER[calendar.get(Calendar.DAY_OF_WEEK) - 1] + "";
    341     }
    342 
    343     /**
    344      * 将当前时间转换成要展示的形式
    345      *
    346      * @param calendar
    347      * @return
    348      */
    349     public static String getCurrentDay(Calendar calendar) {
    350         return getDay(calendar) + " 农历" + new CalendarUtil(calendar).getDay()
    351                 + " " + getWeek(calendar);
    352     }
    353 
    354     /**
    355      * 用于获取中国的传统节日
    356      *
    357      * @param month
    358      *            农历的月
    359      * @param day
    360      *            农历日
    361      * @return 中国传统节日
    362      */
    363     private String getChinaCalendarMsg(int year, int month, int day) {
    364         String message = "";
    365         if (((month) == 1) && day == 1) {
    366             message = "春节";
    367         } else if (((month) == 1) && day == 15) {
    368             message = "元宵";
    369         } else if (((month) == 5) && day == 5) {
    370             message = "端午";
    371         } else if ((month == 7) && day == 7) {
    372             message = "七夕";
    373         } else if (((month) == 8) && day == 15) {
    374             message = "中秋";
    375         } else if ((month == 9) && day == 9) {
    376             message = "重阳";
    377         } else if ((month == 12) && day == 8) {
    378             message = "腊八";
    379         } else {
    380             if (month == 12) {
    381                 if ((((monthDays(year, month) == 29) && day == 29))
    382                         || ((((monthDays(year, month) == 30) && day == 30)))) {
    383                     message = "除夕";
    384                 }
    385             }
    386         }
    387         return message;
    388     }
    389 }

    4)

    CalendarView
      1 package com.example.nanchen.mydateviewdemo.view;
      2 
      3 import android.annotation.SuppressLint;
      4 import android.content.Context;
      5 import android.graphics.Color;
      6 import android.text.TextUtils.TruncateAt;
      7 import android.util.AttributeSet;
      8 import android.view.GestureDetector;
      9 import android.view.GestureDetector.OnGestureListener;
     10 import android.view.Gravity;
     11 import android.view.MotionEvent;
     12 import android.view.View;
     13 import android.view.View.OnTouchListener;
     14 import android.view.animation.Animation;
     15 import android.view.animation.Animation.AnimationListener;
     16 import android.view.animation.TranslateAnimation;
     17 import android.widget.GridView;
     18 import android.widget.ImageButton;
     19 import android.widget.LinearLayout;
     20 import android.widget.RelativeLayout;
     21 import android.widget.TextView;
     22 import android.widget.ViewFlipper;
     23 
     24 import com.example.nanchen.mydateviewdemo.R;
     25 
     26 import java.util.ArrayList;
     27 import java.util.Calendar;
     28 import java.util.Date;
     29 import java.util.List;
     30 
     31 /**
     32  * @author nanchen
     33  * @date 16-8-10 上午11:40
     34  */
     35 public class CalendarView extends LinearLayout implements OnTouchListener, AnimationListener, OnGestureListener {
     36 
     37     /**
     38      * 点击日历
     39      */
     40     public interface OnCalendarViewListener {
     41         void onCalendarItemClick(CalendarView view, Date date);
     42     }
     43 
     44     /**
     45      * 顶部控件所占高度
     46      */
     47     private final static int TOP_HEIGHT = 40;
     48     /**
     49      * 日历item中默认id从0xff0000开始
     50      */
     51     private final static int DEFAULT_ID = 0xff0000;
     52 
     53     // 判断手势用
     54     private static final int SWIPE_MIN_DISTANCE = 120;
     55     private static final int SWIPE_MAX_OFF_PATH = 250;
     56     private static final int SWIPE_THRESHOLD_VELOCITY = 200;
     57 
     58     // 屏幕宽度和高度
     59     private int screenWidth;
     60 
     61     // 动画
     62     private Animation slideLeftIn;
     63     private Animation slideLeftOut;
     64     private Animation slideRightIn;
     65     private Animation slideRightOut;
     66     private ViewFlipper viewFlipper;
     67     private GestureDetector mGesture = null;
     68 
     69     /**
     70      * 上一月
     71      */
     72     private GridView gView1;
     73     /**
     74      * 当月
     75      */
     76     private GridView gView2;
     77     /**
     78      * 下一月
     79      */
     80     private GridView gView3;
     81 
     82     boolean bIsSelection = false;// 是否是选择事件发生
     83     private Calendar calStartDate = Calendar.getInstance();// 当前显示的日历
     84     private Calendar calSelected = Calendar.getInstance(); // 选择的日历
     85     private CalendarGridViewAdapter gAdapter;
     86     private CalendarGridViewAdapter gAdapter1;
     87     private CalendarGridViewAdapter gAdapter3;
     88 
     89     private LinearLayout mMainLayout;
     90     private TextView mTitle; // 显示年月
     91 
     92     private int iMonthViewCurrentMonth = 0; // 当前视图月
     93     private int iMonthViewCurrentYear = 0; // 当前视图年
     94 
     95     private static final int caltitleLayoutID = 66; // title布局ID
     96     private static final int calLayoutID = 55; // 日历布局ID
     97     private Context mContext;
     98 
     99     /**
    100      * 标注日期
    101      */
    102     private final List<Date> markDates;
    103 
    104     private OnCalendarViewListener mListener;
    105 
    106     public CalendarView(Context context) {
    107         this(context, null);
    108     }
    109 
    110     public CalendarView(Context context, AttributeSet attrs) {
    111         super(context, attrs);
    112         // TODO Auto-generated constructor stub
    113         mContext = context;
    114         markDates = new ArrayList<>();
    115         init();
    116     }
    117 
    118     // 初始化相关工作
    119     protected void init() {
    120         // 得到屏幕的宽度
    121         screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
    122 
    123         // 滑动的动画
    124         slideLeftIn = new TranslateAnimation(screenWidth, 0, 0, 0);
    125         slideLeftIn.setDuration(400);
    126         slideLeftIn.setAnimationListener(this);
    127         slideLeftOut = new TranslateAnimation(0, -screenWidth, 0, 0);
    128         slideLeftOut.setDuration(400);
    129         slideLeftOut.setAnimationListener(this);
    130         slideRightIn = new TranslateAnimation(-screenWidth, 0, 0, 0);
    131         slideRightIn.setDuration(400);
    132         slideRightIn.setAnimationListener(this);
    133         slideRightOut = new TranslateAnimation(0, screenWidth, 0, 0);
    134         slideRightOut.setDuration(400);
    135         slideRightOut.setAnimationListener(this);
    136 
    137         // 手势操作
    138         mGesture = new GestureDetector(mContext, this);
    139 
    140         // 获取到当前日期
    141         UpdateStartDateForMonth();
    142         // 绘制界面
    143         setOrientation(LinearLayout.HORIZONTAL);
    144         mMainLayout = new LinearLayout(mContext);
    145         LinearLayout.LayoutParams main_params = new LinearLayout.LayoutParams(
    146                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    147         mMainLayout.setLayoutParams(main_params);
    148         mMainLayout.setGravity(Gravity.CENTER_HORIZONTAL);
    149         mMainLayout.setOrientation(LinearLayout.VERTICAL);
    150         addView(mMainLayout);
    151 
    152         // 顶部控件
    153         generateTopView();
    154 
    155         // 中间显示星期
    156         generateWeekGirdView();
    157 
    158         // 底部显示日历
    159         viewFlipper = new ViewFlipper(mContext);
    160         RelativeLayout.LayoutParams fliper_params = new RelativeLayout.LayoutParams(
    161                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    162         fliper_params.addRule(RelativeLayout.BELOW, caltitleLayoutID);
    163         mMainLayout.addView(viewFlipper, fliper_params);
    164         generateClaendarGirdView();
    165 
    166         // 最下方的一条线条
    167         LinearLayout br = new LinearLayout(mContext);
    168         br.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));
    169         LinearLayout.LayoutParams params_br = new LinearLayout.LayoutParams(
    170                 LayoutParams.MATCH_PARENT, 3);
    171         mMainLayout.addView(br, params_br);
    172     }
    173 
    174     /**
    175      * 生成顶部控件
    176      */
    177     @SuppressWarnings("deprecation")
    178     private void generateTopView() {
    179         // 顶部显示上一个下一个,以及当前年月
    180         RelativeLayout top = new RelativeLayout(mContext);
    181         top.setBackgroundColor(Color.argb(0xff, 0x0e, 0x6b, 0xc2));
    182         LinearLayout.LayoutParams top_params = new LinearLayout.LayoutParams(
    183                 LayoutParams.MATCH_PARENT,
    184                 ViewUtil.dip2px(mContext, TOP_HEIGHT));
    185         top.setLayoutParams(top_params);
    186         mMainLayout.addView(top);
    187         // 左方按钮、中间日期显示、右方按钮
    188         mTitle = new TextView(mContext);
    189         android.widget.RelativeLayout.LayoutParams title_params = new android.widget.RelativeLayout.LayoutParams(
    190                 android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,
    191                 android.widget.RelativeLayout.LayoutParams.MATCH_PARENT);
    192         mTitle.setLayoutParams(title_params);
    193         mTitle.setTextColor(Color.WHITE);
    194         mTitle.setTextSize(18);
    195         mTitle.setFocusableInTouchMode(true);
    196         mTitle.setMarqueeRepeatLimit(-1);
    197         mTitle.setEllipsize(TruncateAt.MARQUEE);
    198         mTitle.setSingleLine(true);
    199         mTitle.setGravity(Gravity.CENTER);
    200         mTitle.setHorizontallyScrolling(true);
    201         mTitle.setText("2014年9月");
    202         top.addView(mTitle);
    203 
    204         // 左方按钮
    205         ImageButton mLeftView = new ImageButton(mContext);
    206 
    218 
    219         mLeftView.setBackgroundResource(R.drawable.month_pre_selector);
    220         android.widget.RelativeLayout.LayoutParams leftPP = new android.widget.RelativeLayout.LayoutParams(
    221                 ViewUtil.dip2px(mContext, 25), ViewUtil.dip2px(mContext, 22));
    222         leftPP.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    223         leftPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
    224         leftPP.setMargins(20, 0, 0, 0);
    225         mLeftView.setLayoutParams(leftPP);
    226         mLeftView.setOnClickListener(new OnClickListener() {
    227 
    228             @Override
    229             public void onClick(View v) {
    230                 // TODO Auto-generated method stub
    231                 viewFlipper.setInAnimation(slideRightIn);
    232                 viewFlipper.setOutAnimation(slideRightOut);
    233                 viewFlipper.showPrevious();
    234                 setPrevViewItem();
    235             }
    236         });
    237         top.addView(mLeftView);
    238 
    239         // 右方按钮
    240         ImageButton mRightView = new ImageButton(mContext);
    241 
    253 
    254         mRightView.setBackgroundResource(R.drawable.month_next_selector);
    255 
    256         android.widget.RelativeLayout.LayoutParams rightPP = new android.widget.RelativeLayout.LayoutParams(
    257                 ViewUtil.dip2px(mContext, 25), ViewUtil.dip2px(mContext, 22));
    258         rightPP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    259         rightPP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
    260         rightPP.setMargins(0, 0, 20, 0);
    261         mRightView.setLayoutParams(rightPP);
    262         mRightView.setOnClickListener(new OnClickListener() {
    263 
    264             @Override
    265             public void onClick(View v) {
    266                 // TODO Auto-generated method stub
    267                 viewFlipper.setInAnimation(slideLeftIn);
    268                 viewFlipper.setOutAnimation(slideLeftOut);
    269                 viewFlipper.showNext();
    270                 setNextViewItem();
    271             }
    272         });
    273         top.addView(mRightView);
    274     }
    275 
    276     /**
    277      * 生成中间显示week
    278      */
    279     private void generateWeekGirdView() {
    280         GridView gridView = new GridView(mContext);
    281         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    282                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    283         gridView.setLayoutParams(params);
    284         gridView.setNumColumns(7);// 设置每行列数
    285         gridView.setGravity(Gravity.CENTER_VERTICAL);// 位置居中
    286         gridView.setVerticalSpacing(1);// 垂直间隔
    287         gridView.setHorizontalSpacing(1);// 水平间隔
    288         gridView.setBackgroundColor(Color.argb(0xff, 0xe3, 0xee, 0xf4));
    289 
    290         int i = screenWidth / 7;
    291         int j = screenWidth - (i * 7);
    292         int x = j / 2;
    293         gridView.setPadding(x, 0, 0, 0);// 居中
    294         WeekGridAdapter weekAdapter = new WeekGridAdapter(mContext);
    295         gridView.setAdapter(weekAdapter);// 设置菜单Adapter
    296         mMainLayout.addView(gridView);
    297     }
    298 
    299     /**
    300      * 生成底部日历
    301      */
    302     private void generateClaendarGirdView() {
    303         Calendar tempSelected1 = Calendar.getInstance(); // 临时
    304         Calendar tempSelected2 = Calendar.getInstance(); // 临时
    305         Calendar tempSelected3 = Calendar.getInstance(); // 临时
    306         tempSelected1.setTime(calStartDate.getTime());
    307         tempSelected2.setTime(calStartDate.getTime());
    308         tempSelected3.setTime(calStartDate.getTime());
    309 
    310         gView1 = new CalendarGridView(mContext);
    311         tempSelected1.add(Calendar.MONTH, -1);
    312         gAdapter1 = new CalendarGridViewAdapter(mContext, tempSelected1,
    313                 markDates);
    314         gView1.setAdapter(gAdapter1);// 设置菜单Adapter
    315         gView1.setId(calLayoutID);
    316 
    317         gView2 = new CalendarGridView(mContext);
    318         gAdapter = new CalendarGridViewAdapter(mContext, tempSelected2,
    319                 markDates);
    320         gView2.setAdapter(gAdapter);// 设置菜单Adapter
    321         gView2.setId(calLayoutID);
    322 
    323         gView3 = new CalendarGridView(mContext);
    324         tempSelected3.add(Calendar.MONTH, 1);
    325         gAdapter3 = new CalendarGridViewAdapter(mContext, tempSelected3,
    326                 markDates);
    327         gView3.setAdapter(gAdapter3);// 设置菜单Adapter
    328         gView3.setId(calLayoutID);
    329 
    330         gView2.setOnTouchListener(this);
    331         gView1.setOnTouchListener(this);
    332         gView3.setOnTouchListener(this);
    333 
    334         if (viewFlipper.getChildCount() != 0) {
    335             viewFlipper.removeAllViews();
    336         }
    337 
    338         viewFlipper.addView(gView2);
    339         viewFlipper.addView(gView3);
    340         viewFlipper.addView(gView1);
    341 
    342         String title = calStartDate.get(Calendar.YEAR)
    343                 + "年"
    344                 + NumberHelper.LeftPad_Tow_Zero(calStartDate
    345                 .get(Calendar.MONTH) + 1) + "月";
    346         mTitle.setText(title);
    347     }
    348 
    349     // 上一个月
    350     private void setPrevViewItem() {
    351         iMonthViewCurrentMonth--;// 当前选择月--
    352         // 如果当前月为负数的话显示上一年
    353         if (iMonthViewCurrentMonth == -1) {
    354             iMonthViewCurrentMonth = 11;
    355             iMonthViewCurrentYear--;
    356         }
    357         calStartDate.set(Calendar.DAY_OF_MONTH, 1); // 设置日为当月1日
    358         calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth); // 设置月
    359         calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear); // 设置年
    360     }
    361 
    362     // 下一个月
    363     private void setNextViewItem() {
    364         iMonthViewCurrentMonth++;
    365         if (iMonthViewCurrentMonth == 12) {
    366             iMonthViewCurrentMonth = 0;
    367             iMonthViewCurrentYear++;
    368         }
    369         calStartDate.set(Calendar.DAY_OF_MONTH, 1);
    370         calStartDate.set(Calendar.MONTH, iMonthViewCurrentMonth);
    371         calStartDate.set(Calendar.YEAR, iMonthViewCurrentYear);
    372     }
    373 
    374     // 根据改变的日期更新日历
    375     // 填充日历控件用
    376     private void UpdateStartDateForMonth() {
    377         calStartDate.set(Calendar.DATE, 1); // 设置成当月第一天
    378         iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月
    379         iMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);// 得到当前日历显示的年
    380 
    381         // 星期一是2 星期天是1 填充剩余天数
    382         int iDay = 0;
    383         int iFirstDayOfWeek = Calendar.MONDAY;
    384         int iStartDay = iFirstDayOfWeek;
    385         if (iStartDay == Calendar.MONDAY) {
    386             iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
    387             if (iDay < 0)
    388                 iDay = 6;
    389         }
    390         if (iStartDay == Calendar.SUNDAY) {
    391             iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
    392             if (iDay < 0)
    393                 iDay = 6;
    394         }
    395         calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
    396     }
    397 
    398     /**
    399      * 设置标注的日期
    400      *
    401      * @param markDates
    402      */
    403     public void setMarkDates(List<Date> markDates) {
    404         this.markDates.clear();
    405         this.markDates.addAll(markDates);
    406         gAdapter.notifyDataSetChanged();
    407         gAdapter1.notifyDataSetChanged();
    408         gAdapter3.notifyDataSetChanged();
    409     }
    410 
    411     /**
    412      * 设置点击日历监听
    413      *
    414      * @param listener
    415      */
    416     public void setOnCalendarViewListener(OnCalendarViewListener listener) {
    417         this.mListener = listener;
    418     }
    419 
    420     @Override
    421     public boolean onDown(MotionEvent e) {
    422         // TODO Auto-generated method stub
    423         return false;
    424     }
    425 
    426     @SuppressLint("ClickableViewAccessibility")
    427     @Override
    428     public boolean onTouch(View v, MotionEvent event) {
    429         return mGesture.onTouchEvent(event);
    430     }
    431 
    432     @Override
    433     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    434                            float velocityY) {
    435         // TODO Auto-generated method stub
    436         try {
    437             if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
    438                 return false;
    439             // right to left swipe
    440             if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
    441                     && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    442                 viewFlipper.setInAnimation(slideLeftIn);
    443                 viewFlipper.setOutAnimation(slideLeftOut);
    444                 viewFlipper.showNext();
    445                 setNextViewItem();
    446                 return true;
    447 
    448             } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
    449                     && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    450                 viewFlipper.setInAnimation(slideRightIn);
    451                 viewFlipper.setOutAnimation(slideRightOut);
    452                 viewFlipper.showPrevious();
    453                 setPrevViewItem();
    454                 return true;
    455 
    456             }
    457         } catch (Exception e) {
    458             // nothing
    459         }
    460         return false;
    461     }
    462 
    463     @Override
    464     public void onLongPress(MotionEvent e) {
    465         // TODO Auto-generated method stub
    466 
    467     }
    468 
    469     @Override
    470     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
    471                             float distanceY) {
    472         // TODO Auto-generated method stub
    473         return false;
    474     }
    475 
    476     @Override
    477     public void onShowPress(MotionEvent e) {
    478         // TODO Auto-generated method stub
    479 
    480     }
    481 
    482     @Override
    483     public boolean onSingleTapUp(MotionEvent e) {
    484         // TODO Auto-generated method stub
    485         // 得到当前选中的是第几个单元格
    486         int pos = gView2.pointToPosition((int) e.getX(), (int) e.getY());
    487         LinearLayout txtDay = (LinearLayout) gView2.findViewById(pos
    488                 + DEFAULT_ID);
    489         if (txtDay != null) {
    490             if (txtDay.getTag() != null) {
    491                 Date date = (Date) txtDay.getTag();
    492                 calSelected.setTime(date);
    493 
    494                 gAdapter.setSelectedDate(calSelected);
    495                 gAdapter.notifyDataSetChanged();
    496 
    497                 gAdapter1.setSelectedDate(calSelected);
    498                 gAdapter1.notifyDataSetChanged();
    499 
    500                 gAdapter3.setSelectedDate(calSelected);
    501                 gAdapter3.notifyDataSetChanged();
    502                 if (mListener != null)
    503                     mListener.onCalendarItemClick(this, date);
    504             }
    505         }
    506         return false;
    507     }
    508 
    509     @Override
    510     public void onAnimationEnd(Animation animation) {
    511         // TODO Auto-generated method stub
    512         generateClaendarGirdView();
    513     }
    514 
    515     @Override
    516     public void onAnimationRepeat(Animation animation) {
    517         // TODO Auto-generated method stub
    518 
    519     }
    520 
    521     @Override
    522     public void onAnimationStart(Animation animation) {
    523         // TODO Auto-generated method stub
    524 
    525     }
    526 }

    5)

    GregorianUtil
     1 package com.example.nanchen.mydateviewdemo.view;
     2 
     3 import java.util.Calendar;
     4 
     5 /**
     6  * 对公历日期的处理类
     7  * @author nanchen
     8  * @date 16-8-10 上午11:37
     9  */
    10 public class GregorianUtil {
    11     private final static String[][] GRE_FESTVIAL = {
    12             // 一月
    13             { "元旦", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    14                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    15             // 二月
    16             { "", "", "", "", "", "", "", "", "", "", "", "", "", "情人", "", "",
    17                     "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    18             // 三月
    19             { "", "", "", "", "", "", "", "妇女", "", "", "", "植树", "", "", "",
    20                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    21                     "" },
    22             // 四月
    23             { "愚人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    24                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    25             // 五月
    26             { "劳动", "", "", "青年", "", "", "", "", "", "", "", "", "", "", "",
    27                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    28                     "" },
    29             // 六月
    30             { "儿童", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    31                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    32             // 七月
    33             { "建党", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    34                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    35             // 八月
    36             { "建军", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    37                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    38             // 九月
    39             { "", "", "", "", "", "", "", "", "", "教师", "", "", "", "", "", "",
    40                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    41             // 十月
    42             { "国庆", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    43                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    44             // 十一月
    45             { "", "", "", "", "", "", "", "", "", "", "光棍", "", "", "", "", "",
    46                     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
    47             // 十二月
    48             { "艾滋病", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    49                     "", "", "", "", "", "", "", "", "", "圣诞", "", "", "", "",
    50                     "", "" }, };
    51     private int mMonth;
    52     private int mDay;
    53 
    54     public GregorianUtil(Calendar calendar) {
    55         mMonth = calendar.get(Calendar.MONTH);
    56         mDay = calendar.get(Calendar.DATE);
    57     }
    58 
    59     public String getGremessage() {
    60         return GRE_FESTVIAL[mMonth][mDay - 1];
    61     }
    62 }

    6)

     1 package com.example.nanchen.mydateviewdemo.view;
     2 
     3 /**
     4  * @author nanchen
     5  * @date 16-8-10 上午11:38
     6  */
     7 public class NumberHelper {
     8     public static String LeftPad_Tow_Zero(int str) {
     9         java.text.DecimalFormat format = new java.text.DecimalFormat("00");
    10         return format.format(str);
    11     }
    12 }

    7)

    SolarTermsUtil
      1 package com.example.nanchen.mydateviewdemo.view;
      2 
      3 import java.util.Calendar;
      4 
      5 /**
      6  * 主要用于把公历日期处理成24节气
      7  * @author nanchen
      8  * @date 16-8-10 上午11:38
      9  */
     10 public class SolarTermsUtil {
     11     /**
     12      * 计算得到公历的年份
     13      */
     14     private int gregorianYear;
     15 
     16     /**
     17      * 计算得到公历的月份
     18      */
     19     private int gregorianMonth;
     20 
     21     /**
     22      * 用于计算得到公历的日期
     23      */
     24     private int gregorianDate;
     25 
     26     private int chineseYear;
     27     private int chineseMonth;
     28     private int chineseDate;
     29 
     30     // 初始日,公历农历对应日期:
     31     // 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日
     32     private static int baseYear = 1901;
     33     private static int baseMonth = 1;
     34     private static int baseDate = 1;
     35     private static int baseIndex = 0;
     36     private static int baseChineseYear = 4598 - 1;
     37     private static int baseChineseMonth = 11;
     38     private static int baseChineseDate = 11;
     39     private static char[] daysInGregorianMonth = { 31, 28, 31, 30, 31, 30, 31,
     40             31, 30, 31, 30, 31 };
     41 
     42     private int sectionalTerm;
     43     private int principleTerm;
     44 
     45     private static char[][] sectionalTermMap = {
     46             { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5,
     47                     5, 5, 5, 4, 5, 5 },
     48             { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3,
     49                     3, 4, 4, 3, 3, 3 },
     50             { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
     51                     5, 5, 4, 5, 5, 5, 5 },
     52             { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4,
     53                     4, 5, 4, 4, 4, 4, 5 },
     54             { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,
     55                     5, 5, 4, 5, 5, 5, 5 },
     56             { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5,
     57                     5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 },
     58             { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
     59                     7, 7, 6, 6, 6, 7, 7 },
     60             { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
     61                     7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 },
     62             { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,
     63                     7, 7, 6, 7, 7, 7, 7 },
     64             { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8,
     65                     8, 8, 7, 7, 8, 8, 8 },
     66             { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7,
     67                     7, 7, 6, 6, 7, 7, 7 },
     68             { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,
     69                     7, 7, 6, 6, 6, 7, 7 } };
     70     private static char[][] sectionalTermYear = {
     71             { 13, 49, 85, 117, 149, 185, 201, 250, 250 },
     72             { 13, 45, 81, 117, 149, 185, 201, 250, 250 },
     73             { 13, 48, 84, 112, 148, 184, 200, 201, 250 },
     74             { 13, 45, 76, 108, 140, 172, 200, 201, 250 },
     75             { 13, 44, 72, 104, 132, 168, 200, 201, 250 },
     76             { 5, 33, 68, 96, 124, 152, 188, 200, 201 },
     77             { 29, 57, 85, 120, 148, 176, 200, 201, 250 },
     78             { 13, 48, 76, 104, 132, 168, 196, 200, 201 },
     79             { 25, 60, 88, 120, 148, 184, 200, 201, 250 },
     80             { 16, 44, 76, 108, 144, 172, 200, 201, 250 },
     81             { 28, 60, 92, 124, 160, 192, 200, 201, 250 },
     82             { 17, 53, 85, 124, 156, 188, 200, 201, 250 } };
     83     private static char[][] principleTermMap = {
     84             { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20,
     85                     20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20 },
     86             { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19,
     87                     19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18 },
     88             { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21,
     89                     20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20 },
     90             { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20,
     91                     19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20 },
     92             { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21,
     93                     20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21 },
     94             { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22,
     95                     21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21 },
     96             { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23,
     97                     22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23 },
     98             { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
     99                     22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
    100             { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,
    101                     22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 },
    102             { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24,
    103                     23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23 },
    104             { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23,
    105                     22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22 },
    106             { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22,
    107                     21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22 } };
    108     private static char[][] principleTermYear = {
    109             { 13, 45, 81, 113, 149, 185, 201 },
    110             { 21, 57, 93, 125, 161, 193, 201 },
    111             { 21, 56, 88, 120, 152, 188, 200, 201 },
    112             { 21, 49, 81, 116, 144, 176, 200, 201 },
    113             { 17, 49, 77, 112, 140, 168, 200, 201 },
    114             { 28, 60, 88, 116, 148, 180, 200, 201 },
    115             { 25, 53, 84, 112, 144, 172, 200, 201 },
    116             { 29, 57, 89, 120, 148, 180, 200, 201 },
    117             { 17, 45, 73, 108, 140, 168, 200, 201 },
    118             { 28, 60, 92, 124, 160, 192, 200, 201 },
    119             { 16, 44, 80, 112, 148, 180, 200, 201 },
    120             { 17, 53, 88, 120, 156, 188, 200, 201 } };
    121 
    122     private static char[] chineseMonths = {
    123             // 农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数,
    124             // 前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。
    125             0x00, 0x04, 0xad, 0x08, 0x5a, 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64,
    126             0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08,
    127             0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94,
    128             0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02,
    129             0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56,
    130             0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05,
    131             0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec,
    132             0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a,
    133             0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52,
    134             0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02,
    135             0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a,
    136             0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09,
    137             0xb0, 0x39, 0x64, 0x05, 0x25, 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d,
    138             0x54, 0xad, 0x04, 0xda, 0x04, 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85,
    139             0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a,
    140             0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d,
    141             0x2a, 0x09, 0x56, 0x01, 0xad, 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1,
    142             0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54,
    143             0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51,
    144             0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52,
    145             0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d,
    146             0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45,
    147             0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda,
    148             0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a,
    149             0x96, 0x04, 0xad, 0xb0, 0xad, 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4,
    150             0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22,
    151             0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49,
    152             0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01,
    153             0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa,
    154             0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a,
    155             0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5,
    156             0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05,
    157             0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69,
    158             0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09,
    159             0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4,
    160             0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04,
    161             0x74, 0x05, 0xb0, 0x25, 0x54, 0x03 };
    162 
    163     /**
    164      * 用于保存24节气
    165      */
    166     private static String[] principleTermNames = { "大寒", "雨水", "春分", "谷雨",
    167             "小满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至" };
    168     /**
    169      * 用于保存24节气
    170      */
    171     private static String[] sectionalTermNames = { "小寒", "立春", "惊蛰", "清明",
    172             "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪" };
    173 
    174     public SolarTermsUtil(Calendar calendar) {
    175         gregorianYear = calendar.get(Calendar.YEAR);
    176         gregorianMonth = calendar.get(Calendar.MONTH) + 1;
    177         gregorianDate = calendar.get(Calendar.DATE);
    178         computeChineseFields();
    179         computeSolarTerms();
    180     }
    181 
    182     public int computeChineseFields() {
    183         if (gregorianYear < 1901 || gregorianYear > 2100)
    184             return 1;
    185         int startYear = baseYear;
    186         int startMonth = baseMonth;
    187         int startDate = baseDate;
    188         chineseYear = baseChineseYear;
    189         chineseMonth = baseChineseMonth;
    190         chineseDate = baseChineseDate;
    191         // 第二个对应日,用以提高计算效率
    192         // 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日
    193         if (gregorianYear >= 2000) {
    194             startYear = baseYear + 99;
    195             startMonth = 1;
    196             startDate = 1;
    197             chineseYear = baseChineseYear + 99;
    198             chineseMonth = 11;
    199             chineseDate = 25;
    200         }
    201         int daysDiff = 0;
    202         for (int i = startYear; i < gregorianYear; i++) {
    203             daysDiff += 365;
    204             if (isGregorianLeapYear(i))
    205                 daysDiff += 1; // leap year
    206         }
    207         for (int i = startMonth; i < gregorianMonth; i++) {
    208             daysDiff += daysInGregorianMonth(gregorianYear, i);
    209         }
    210         daysDiff += gregorianDate - startDate;
    211 
    212         chineseDate += daysDiff;
    213         int lastDate = daysInChineseMonth(chineseYear, chineseMonth);
    214         int nextMonth = nextChineseMonth(chineseYear, chineseMonth);
    215         while (chineseDate > lastDate) {
    216             if (Math.abs(nextMonth) < Math.abs(chineseMonth))
    217                 chineseYear++;
    218             chineseMonth = nextMonth;
    219             chineseDate -= lastDate;
    220             lastDate = daysInChineseMonth(chineseYear, chineseMonth);
    221             nextMonth = nextChineseMonth(chineseYear, chineseMonth);
    222         }
    223         return 0;
    224     }
    225 
    226     public int computeSolarTerms() {
    227         if (gregorianYear < 1901 || gregorianYear > 2100)
    228             return 1;
    229         sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);
    230         principleTerm = principleTerm(gregorianYear, gregorianMonth);
    231         return 0;
    232     }
    233 
    234     public static int sectionalTerm(int y, int m) {
    235         if (y < 1901 || y > 2100)
    236             return 0;
    237         int index = 0;
    238         int ry = y - baseYear + 1;
    239         while (ry >= sectionalTermYear[m - 1][index])
    240             index++;
    241         int term = sectionalTermMap[m - 1][4 * index + ry % 4];
    242         if ((ry == 121) && (m == 4))
    243             term = 5;
    244         if ((ry == 132) && (m == 4))
    245             term = 5;
    246         if ((ry == 194) && (m == 6))
    247             term = 6;
    248         return term;
    249     }
    250 
    251     public static int principleTerm(int y, int m) {
    252         if (y < 1901 || y > 2100)
    253             return 0;
    254         int index = 0;
    255         int ry = y - baseYear + 1;
    256         while (ry >= principleTermYear[m - 1][index])
    257             index++;
    258         int term = principleTermMap[m - 1][4 * index + ry % 4];
    259         if ((ry == 171) && (m == 3))
    260             term = 21;
    261         if ((ry == 181) && (m == 5))
    262             term = 21;
    263         return term;
    264     }
    265 
    266     /**
    267      * 用于判断输入的年份是否为闰年
    268      *
    269      * @param year
    270      *            输入的年份
    271      * @return true 表示闰年
    272      */
    273     public static boolean isGregorianLeapYear(int year) {
    274         boolean isLeap = false;
    275         if (year % 4 == 0)
    276             isLeap = true;
    277         if (year % 100 == 0)
    278             isLeap = false;
    279         if (year % 400 == 0)
    280             isLeap = true;
    281         return isLeap;
    282     }
    283 
    284     public static int daysInGregorianMonth(int y, int m) {
    285         int d = daysInGregorianMonth[m - 1];
    286         if (m == 2 && isGregorianLeapYear(y))
    287             d++; // 公历闰年二月多一天
    288         return d;
    289     }
    290 
    291     public static int daysInChineseMonth(int y, int m) {
    292         // 注意:闰月 m < 0
    293         int index = y - baseChineseYear + baseIndex;
    294         int v = 0;
    295         int l = 0;
    296         int d = 30;
    297         if (1 <= m && m <= 8) {
    298             v = chineseMonths[2 * index];
    299             l = m - 1;
    300             if (((v >> l) & 0x01) == 1)
    301                 d = 29;
    302         } else if (9 <= m && m <= 12) {
    303             v = chineseMonths[2 * index + 1];
    304             l = m - 9;
    305             if (((v >> l) & 0x01) == 1)
    306                 d = 29;
    307         } else {
    308             v = chineseMonths[2 * index + 1];
    309             v = (v >> 4) & 0x0F;
    310             if (v != Math.abs(m)) {
    311                 d = 0;
    312             } else {
    313                 d = 29;
    314                 for (int i = 0; i < bigLeapMonthYears.length; i++) {
    315                     if (bigLeapMonthYears[i] == index) {
    316                         d = 30;
    317                         break;
    318                     }
    319                 }
    320             }
    321         }
    322         return d;
    323     }
    324 
    325     public static int nextChineseMonth(int y, int m) {
    326         int n = Math.abs(m) + 1;
    327         if (m > 0) {
    328             int index = y - baseChineseYear + baseIndex;
    329             int v = chineseMonths[2 * index + 1];
    330             v = (v >> 4) & 0x0F;
    331             if (v == m)
    332                 n = -m;
    333         }
    334         if (n == 13)
    335             n = 1;
    336         return n;
    337     }
    338 
    339     // 大闰月的闰年年份
    340     private static int[] bigLeapMonthYears = { 6, 14, 19, 25, 33, 36, 38, 41,
    341             44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193 };
    342 
    343     /**
    344      * 用于获取24节气的值
    345      *
    346      * @return 24节气的值
    347      */
    348     public String getSolartermsMsg() {
    349         String str = "";
    350         String gm = String.valueOf(gregorianMonth);
    351         if (gm.length() == 1)
    352             gm = ' ' + gm;
    353         String cm = String.valueOf(Math.abs(chineseMonth));
    354         if (cm.length() == 1)
    355             cm = ' ' + cm;
    356         String gd = String.valueOf(gregorianDate);
    357         if (gd.length() == 1)
    358             gd = ' ' + gd;
    359         String cd = String.valueOf(chineseDate);
    360         if (cd.length() == 1)
    361             cd = ' ' + cd;
    362         if (gregorianDate == sectionalTerm) {
    363             str = " " + sectionalTermNames[gregorianMonth - 1];
    364         } else if (gregorianDate == principleTerm) {
    365             str = " " + principleTermNames[gregorianMonth - 1];
    366         }
    367         return str;
    368     }
    369 }

    8)

    StringUtil
     1 package com.example.nanchen.mydateviewdemo.view;
     2 
     3 /**
     4  * @author nanchen
     5  * @date 16-8-10 上午11:39
     6  */
     7 public class StringUtil {
     8 
     9     /**
    10      * 判断是否为null或空值
    11      *
    12      * @param str
    13      *            String
    14      * @return true or false
    15      */
    16     public static boolean isNullOrEmpty(String str) {
    17         return str == null || str.trim().length() == 0;
    18     }
    19 
    20     /**
    21      * 判断str1和str2是否相同
    22      *
    23      * @param str1
    24      *            str1
    25      * @param str2
    26      *            str2
    27      * @return true or false
    28      */
    29     public static boolean equals(String str1, String str2) {
    30         return str1 == str2 || str1 != null && str1.equals(str2);
    31     }
    32 
    33     /**
    34      * 判断str1和str2是否相同(不区分大小写)
    35      *
    36      * @param str1
    37      *            str1
    38      * @param str2
    39      *            str2
    40      * @return true or false
    41      */
    42     public static boolean equalsIgnoreCase(String str1, String str2) {
    43         return str1 != null && str1.equalsIgnoreCase(str2);
    44     }
    45 
    46     /**
    47      * 判断字符串str1是否包含字符串str2
    48      *
    49      * @param str1
    50      *            源字符串
    51      * @param str2
    52      *            指定字符串
    53      * @return true源字符串包含指定字符串,false源字符串不包含指定字符串
    54      */
    55     public static boolean contains(String str1, String str2) {
    56         return str1 != null && str1.contains(str2);
    57     }
    58 
    59     /**
    60      * 判断字符串是否为空,为空则返回一个空值,不为空则返回原字符串
    61      *
    62      * @param str
    63      *            待判断字符串
    64      * @return 判断后的字符串
    65      */
    66     public static String getString(String str) {
    67         return str == null ? "" : str;
    68     }
    69 }

    9)

    ViewUtil
      1 package com.example.nanchen.mydateviewdemo.view;
      2 
      3 import android.content.Context;
      4 import android.content.res.Resources;
      5 
      6 /**
      7  * 辅助类
      8  *
      9  * @author nanchen
     10  * @date 16-8-10 上午11:39
     11  */
     12 public class ViewUtil {
     13     /**
     14      * 获取屏幕的宽度
     15      * @param context
     16      * @return
     17      */
     18     public int getScreenWidth(Context context) {
     19         Resources res = context.getResources();
     20         return res.getDisplayMetrics().widthPixels;
     21     }
     22 
     23     /**
     24      * 获取屏幕高度
     25      * @param context
     26      * @return
     27      */
     28     public int getScreenHeight(Context context) {
     29         Resources res = context.getResources();
     30         return res.getDisplayMetrics().heightPixels;
     31     }
     32 
     33     /**
     34      * 描述:根据分辨率获得字体大小.
     35      *
     36      * @param screenWidth the screen width
     37      * @param screenHeight the screen height
     38      * @param textSize the text size
     39      * @return the int
     40      */
     41     public static int resizeTextSize(int screenWidth,int screenHeight,int textSize){
     42         float ratio =  1;
     43         try {
     44             float ratioWidth = (float)screenWidth / 480;
     45             float ratioHeight = (float)screenHeight / 800;
     46             ratio = Math.min(ratioWidth, ratioHeight);
     47         } catch (Exception e) {
     48         }
     49         return Math.round(textSize * ratio);
     50     }
     51 
     52     /**
     53      *
     54      * 描述:dip转换为px
     55      * @param context
     56      * @param dipValue
     57      * @return
     58      * @throws
     59      */
     60     public static int dip2px(Context context, float dipValue) {
     61         final float scale = context.getResources().getDisplayMetrics().density;
     62         return Math.round(dipValue * scale);
     63     }
     64 
     65     /**
     66      *
     67      * 描述:px转换为dip
     68      * @param context
     69      * @param pxValue
     70      * @return
     71      * @throws
     72      */
     73     public static int px2dip(Context context, float pxValue) {
     74         final float scale = context.getResources().getDisplayMetrics().density;
     75         return Math.round(pxValue / scale);
     76     }
     77 
     78     /**
     79      *
     80      * 描述:px转换为sp
     81      * @param context
     82      * @param pxValue
     83      * @return
     84      * @throws
     85      */
     86     public static int px2sp(Context context, float pxValue) {
     87         final float scale = context.getResources().getDisplayMetrics().scaledDensity;
     88         return Math.round(pxValue / scale);
     89     }
     90 
     91     /**
     92      *
     93      * 描述:sp转换为px
     94      * @param context
     95      * @param spValue
     96      * @return
     97      * @throws
     98      */
     99     public static int sp2px(Context context, float spValue) {
    100         final float scale = context.getResources().getDisplayMetrics().scaledDensity;
    101         return Math.round(spValue * scale);
    102     }
    103 }

    10)

    WeekGridAdapter
     1 package com.example.nanchen.mydateviewdemo.view;
     2 
     3 import android.content.Context;
     4 import android.graphics.Color;
     5 import android.view.Gravity;
     6 import android.view.View;
     7 import android.view.ViewGroup;
     8 import android.view.ViewGroup.LayoutParams;
     9 import android.widget.BaseAdapter;
    10 import android.widget.TextView;
    11 
    12 import com.example.nanchen.mydateviewdemo.R;
    13 
    14 /**
    15  * 显示week的布局adapter
    16  * @author nanchen
    17  * @date 16-8-10 上午11:39
    18  */
    19 public class WeekGridAdapter extends BaseAdapter {
    20     final String[] titles = new String[] { "日", "一", "二", "三", "四", "五", "六" };
    21     private Context mContext;
    22 
    23     public WeekGridAdapter(Context context) {
    24         this.mContext = context;
    25     }
    26 
    27     @Override
    28     public int getCount() {
    29         return titles.length;
    30     }
    31 
    32     @Override
    33     public Object getItem(int position) {
    34         return titles[position];
    35     }
    36 
    37     @Override
    38     public long getItemId(int position) {
    39         return position;
    40     }
    41 
    42     @Override
    43     public View getView(int position, View convertView, ViewGroup parent) {
    44         TextView week = new TextView(mContext);
    45         android.view.ViewGroup.LayoutParams week_params = new LayoutParams(
    46                 android.view.ViewGroup.LayoutParams.MATCH_PARENT,
    47                 android.view.ViewGroup.LayoutParams.MATCH_PARENT);
    48         week.setLayoutParams(week_params);
    49         week.setPadding(0, 0, 0, 0);
    50         week.setGravity(Gravity.CENTER);
    51         week.setFocusable(false);
    52         week.setBackgroundColor(Color.TRANSPARENT);
    53 
    54         if (position == 6) { // 周六
    55             week.setBackgroundColor(R.color.date_weekend_text_color);
    56             week.setTextColor(Color.WHITE);
    57         } else if (position == 0) { // 周日
    58             week.setBackgroundColor(R.color.date_weekend_text_color);
    59             week.setTextColor(Color.WHITE);
    60         } else {
    61             week.setTextColor(Color.BLACK);
    62         }
    63         week.setText(getItem(position)+"");
    64         return week;
    65     }
    66 }

    11)

    MainActivity
     1 package com.example.nanchen.mydateviewdemo;
     2 
     3 import android.os.Bundle;
     4 import android.support.v7.app.AppCompatActivity;
     5 import android.widget.Toast;
     6 
     7 import com.example.nanchen.mydateviewdemo.view.CalendarView;
     8 import com.example.nanchen.mydateviewdemo.view.CalendarView.OnCalendarViewListener;
     9 
    10 import java.text.SimpleDateFormat;
    11 import java.util.ArrayList;
    12 import java.util.Date;
    13 import java.util.List;
    14 import java.util.Locale;
    15 
    16 public class MainActivity extends AppCompatActivity {
    17 
    18     @Override
    19     protected void onCreate(Bundle savedInstanceState) {
    20         super.onCreate(savedInstanceState);
    21         setContentView(R.layout.activity_main);
    22 
    23         //在代码中
    24         CalendarView calendarView = (CalendarView) findViewById(R.id.calender);
    25         //设置标注日期
    26         List<Date> markDates = new ArrayList<>();
    27         markDates.add(new Date());
    28         calendarView.setMarkDates(markDates);
    29 
    30         //设置点击操作
    31         calendarView.setOnCalendarViewListener(new OnCalendarViewListener() {
    32 
    33             @Override
    34             public void onCalendarItemClick(CalendarView view, Date date) {
    35                 final SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
    36                 Toast.makeText(MainActivity.this, format.format(date), Toast.LENGTH_SHORT).show();
    37             }
    38         });
    39     }
    40 }

    12)布局文件

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:tools="http://schemas.android.com/tools"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     tools:context="com.example.nanchen.mydateviewdemo.MainActivity">
     8 
     9     <com.example.nanchen.mydateviewdemo.view.CalendarView
    10         android:id="@+id/calender"
    11         android:background="#fff"
    12         android:layout_width="match_parent"
    13         android:layout_height="wrap_content">
    14 
    15     </com.example.nanchen.mydateviewdemo.view.CalendarView>
    16 </RelativeLayout>

    drawable包下的

    month_next_selector.xml

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
    3     <item android:state_pressed="false" android:drawable="@drawable/right_arrow_pre"/>
    4     <item android:state_pressed="true" android:drawable="@drawable/right_arrow"/>
    5 </selector>

    month_pre_selector.xml

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
    3     <item android:state_pressed="false" android:drawable="@drawable/left_arrow_pre"/>
    4     <item android:state_pressed="true" android:drawable="@drawable/left_arrow"/>
    5 </selector>

    color.xml

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <resources>
     3     <color name="colorPrimary">#3F51B5</color>
     4     <color name="colorPrimaryDark">#303F9F</color>
     5     <color name="colorAccent">#FF4081</color>
     6     <color name="date_pre_color">#44010101</color>
     7     <color name="date_select_color">#66d8ec</color>
     8     <color name="date_text_color">#010101</color>
     9     <color name="date_other_text_color">#dd918d8d</color>
    10     <color name="date_today_text_color">#aaf43ed8</color>
    11 
    12     <color name="date_weekend_text_color">#f27e9d</color>
    13 
    14 </resources>

    项目已同步至github:https://github.com/nanchen2251/MyCalendarViewDemo

    额,楼主很蠢,就这个花了好一阵功夫,但是无私分享给大家,希望大家越来越好,如果你觉得还算有帮助,别忘了右下角点赞~~分享给你我他~

    转载别忘了在醒目位置附上楼主地址哦~谢谢:http://www.cnblogs.com/liushilin/p/5759750.html

    针对小伙伴们说的UI不够美观和代码讲解不够,楼主已经有了修订版,自行食用,地址:http://www.cnblogs.com/liushilin/p/5763717.html

  • 相关阅读:
    简单马周游问题1152siicly
    Sicily 1155. Can I Post the lette
    POJ 1007
    给定2个大小分别为n, m的整数集合,分别存放在两个数组中 int A[n],B[m],输出两个集合的交集。
    算法1--
    GAN
    为什么ConcurrentHashMap是弱一致的
    手写HASHMAP
    千万级规模高性能、高并发的网络架构经验分享
    Web 通信 之 长连接、长轮询(转)
  • 原文地址:https://www.cnblogs.com/liushilin/p/5759750.html
Copyright © 2011-2022 走看看