关注本人的更多博客:http://www.cnblogs.com/liushilin/
该自定义日历控件已经开源:github地址
可能不少的小伙伴都有看楼主昨天发的自定义日历控件,虽然实现功能不多,但也还算将就吧。
没有看的小伙伴如果有兴趣的话可以去看看:http://www.cnblogs.com/liushilin/p/5759750.html
但是看了的小伙伴就很心急了,说楼主上传到gitHub的东西有问题,楼主下载来看了看,基本都没问题吧,没弄好的小伙伴自己再去我的github首页提取哦~因为我还上传了一个新的。
有的小伙伴又不满意了,楼主,你发的东西代码量那么大也搞得很麻烦,小生纵有远大理想,可思前虑后,还是不得正果,倘若楼主能指点一二便好了。
有的小伙伴说,楼主,你的东西就不能封装一下吗?封装一下,方便你我他~
有的小伙伴说,楼主,你的东西是挺不错,但是界面也略丑了吧~这里gank到22楼住的小伙伴说,中间分隔太低,信息太密集,建议添加行间距和留白,希望能做的漂亮些~
......
小主已成功gank到各位的中肯建议,但是不要慌,大家一个一个来。
大家的建议小主都非常地认可,所以楼主觉得把整个东西该封装的算法封装起来,也UI也弄得漂亮一些。
照例先给个运行图吧~
下面给大家讲解一下我们这个自定义日历的简单思路,肯定还是使用GridView的。
由于昨天是纯定义画的UI,所以大家看起来可能有所困难,所以今天楼主简化了UI,把UI放在了xml文件中,供大家食用。
楼主不是废话多的人,具体看代码,代码中我也做了更多的注释。
1)先准备好我们的算法,我们现在把它完全分离。
闰年月的算法应该大家都懂吧。SpecialCalendar.java
三个方法,判断闰年,这个可能只要学程序前面肯定就学了的。
对于判断月份,貌似也不用多说,就一个switch语句,闰年的时候2月是29天,平年是28天。
还有一个判断某一天是星期几的,这个在Calendar中已经很明显了,但是要注意的是Month在calendar中是0-11
1 package com.example.nanchen.calendarviewdemo.view; 2 3 import java.util.Calendar; 4 5 /** 6 * 闰年月算法 7 * 8 * @author nanchen 9 * @date 2016-08-11 08:54:44 10 * 11 */ 12 public class SpecialCalendar { 13 14 private int daysOfMonth = 0; // 某月的天数 15 private int dayOfWeek = 0; // 具体某一天是星期几 16 17 // 判断是否为闰年 18 public boolean isLeapYear(int year) { 19 if (year % 100 == 0 && year % 400 == 0) { 20 return true; 21 } else if (year % 100 != 0 && year % 4 == 0) { 22 return true; 23 } 24 return false; 25 } 26 27 // 得到某月有多少天数 28 public int getDaysOfMonth(boolean isLeapYear, int month) { 29 switch (month) { 30 case 1: 31 case 3: 32 case 5: 33 case 7: 34 case 8: 35 case 10: 36 case 12: 37 daysOfMonth = 31; 38 break; 39 case 4: 40 case 6: 41 case 9: 42 case 11: 43 daysOfMonth = 30; 44 break; 45 case 2: 46 if (isLeapYear) { 47 daysOfMonth = 29; 48 } else { 49 daysOfMonth = 28; 50 } 51 52 } 53 return daysOfMonth; 54 } 55 56 /** 57 * 指定某年中的某月的第一天是星期几 58 */ 59 public int getWeekdayOfMonth(int year, int month) { 60 Calendar cal = Calendar.getInstance(); 61 cal.set(year, month - 1, 1); 62 dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1; 63 return dayOfWeek; 64 } 65 66 }
2)然后带来的是算农历的算法。LunarCalendar.java
就算法本身而言,楼主参考了网上留下的算法。基本就是定义好这些要用的数组,然后考虑完所有的情况。
这里需要心细严谨一些,毕竟你或许错一个参数,一个值就会让你一直搞不出原因,所以写出算法不妨先在Eclipse中看看控制台运行的结果是否正确吧。
高配置随便带Android studio的童鞋当我没说。
这里需要注意的是,我们要做农历,肯定必须想到年份,闰月,闰月是哪个月,这个月有多少天,这些都是需要考虑的。
楼主这简单添加几个节日,节日大家可以随便添加哦。只是一个显示问题。
1 package com.example.nanchen.calendarviewdemo.view; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 import java.util.Locale; 7 8 /** 9 * 农历算法 10 * 11 * @author nanchen 12 * @date 2016-08-11 08-57:24 13 */ 14 public class LunarCalendar { 15 private int year; // 农历的年份 16 private int month; 17 private int day; 18 private String lunarMonth; // 农历的月份 19 public int leapMonth = 0; // 闰的是哪个月 20 21 final static String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"}; 22 static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA); 23 final static long[] lunarInfo = new long[]{ // 24 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, // 25 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, // 26 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, // 27 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, // 28 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, // 29 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, // 30 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, // 31 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, // 32 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, // 33 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 34 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, // 35 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, // 36 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, // 37 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, // 38 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, // 39 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, // 40 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0}; 41 42 // 农历部分假日 43 final static String[] lunarHoliday = new String[]{"0101 春节", "0115 元宵", "0505 端午", "0707 情人", "0715 中元", "0815 中秋", "0909 重阳", "1208 腊八", "1224 小年", "0100 除夕"}; 44 45 // 公历部分节假日 46 final static String[] solarHoliday = new String[]{ // 47 "0101 元旦", "0214 情人", "0308 妇女", "0312 植树", "0315 消费者权益日", "0401 愚人", "0501 劳动", "0504 青年", // 48 "0512 护士", "0601 儿童", "0701 建党", "0801 建军", "0808 父亲", "0910 教师", "0928 孔子诞辰",// 49 "1001 国庆", "1006 老人", "1024 联合国日", "1112 孙中山诞辰纪念", "1220 澳门回归纪念", "1225 圣诞"}; 50 51 /** 52 * 传回农历 y年的总天数 53 * 54 * @param y 年份 55 * @return 该年的总天数 56 */ 57 private static int yearDays(int y) { 58 int i, sum = 348; 59 for (i = 0x8000; i > 0x8; i >>= 1) { 60 if ((lunarInfo[y - 1900] & i) != 0) 61 sum += 1; 62 } 63 return (sum + leapDays(y)); 64 } 65 66 /** 67 * 传回农历 y年闰月的天数 68 * 69 * @param y 年份 70 * @return 改年闰月天数 71 */ 72 private static int leapDays(int y) { 73 if (leapMonth(y) != 0) { 74 if ((lunarInfo[y - 1900] & 0x10000) != 0) 75 return 30; 76 else 77 return 29; 78 } else 79 return 0; 80 } 81 82 /** 83 * 传回农历 y年闰哪个月 1-12 , 没闰传回 0 84 * 85 * @param y 年份 86 * @return 改年闰月的月数 87 */ 88 private static int leapMonth(int y) { 89 return (int) (lunarInfo[y - 1900] & 0b1111); 90 } 91 92 /** 93 * 传回农历 y年m月的总天数 94 * 95 * @param y 年份 96 * @param m 月份 97 * @return 该月份的总天数 98 */ 99 private static int monthDays(int y, int m) { 100 if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) 101 return 29; 102 else 103 return 30; 104 } 105 106 /** 107 * 传回农历 y年的生肖 108 * 109 * @param year 年份 110 * @return 生肖 111 */ 112 public String animalsYear(int year) { 113 final String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; 114 return Animals[(year - 4) % 12]; 115 } 116 117 /** 118 * 传入 月日的offset 传回干支, 0=甲子 119 */ 120 private static String cyclicalm(int num) { 121 final String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; 122 final String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; 123 return (Gan[num % 10] + Zhi[num % 12]); 124 } 125 126 /** 127 * 传入 offset 传回干支, 0=甲子 128 */ 129 public String cyclical(int year) { 130 int num = year - 1900 + 36; 131 return (cyclicalm(num)); 132 } 133 134 public static String getChinaDayString(int day) { 135 String chineseTen[] = {"初", "十", "廿", "卅"}; 136 int n = day % 10 == 0 ? 9 : day % 10 - 1; 137 if (day > 30) 138 return "";