【无私分享】干货!!!一个炫酷的自定义日历控件,摆脱日历时间选择烦恼,纯福利~
最近公司项目中有一个按日期查看信息的功能,楼主本想用之前用的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
作 者:
南 尘
出 处: http://www.cnblogs.com/liushilin/
关于作者:专注于移动前端的项目开发。如有问题或建议,请多多赐教!欢迎加入Android交流群:118116509
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章下部【推荐】或侧边【关注】。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎关注我的公众号,精讲面试、算法、Andrid、Java、Python,旨在打造全网最比心的公众号。