├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── MySignDate.iml ├── MysignDate.gif ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wsg │ │ └── mysigndate │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── wsg │ │ │ ├── mysign │ │ │ └── mydatepicker │ │ │ │ ├── CN.java │ │ │ │ ├── DPBaseTheme.java │ │ │ │ ├── DPCManager.java │ │ │ │ ├── DPCNCalendar.java │ │ │ │ ├── DPCNTheme.java │ │ │ │ ├── DPCalendar.java │ │ │ │ ├── DPDecor.java │ │ │ │ ├── DPInfo.java │ │ │ │ ├── DPLManager.java │ │ │ │ ├── DPMode.java │ │ │ │ ├── DPTManager.java │ │ │ │ ├── DPTheme.java │ │ │ │ ├── DPUSCalendar.java │ │ │ │ ├── DataUtils.java │ │ │ │ ├── DatePicker.java │ │ │ │ ├── DatePicker2.java │ │ │ │ ├── EN.java │ │ │ │ ├── MeasureUtil.java │ │ │ │ ├── MonthView.java │ │ │ │ └── SolarTerm.java │ │ │ └── mysigndate │ │ │ ├── MainActivity.java │ │ │ └── YuanbanDemoActivity.java │ └── res │ │ ├── drawable │ │ ├── box_blue_solid.xml │ │ └── box_gray_solid.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_yuanban.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── wsg │ └── mysigndate │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MySignDate -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | $USER_HOME$/.subversion 48 | 49 | 50 | 51 | 52 | 53 | 1.8 54 | 55 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MySignDate.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /MysignDate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wushaoge/MySignDate/113fe807bf1e6b00e705421eaf4b6778b618e031/MysignDate.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | demo效果图 2 | ![image](https://github.com/wushaoge/MySignDate/blob/master/MysignDate.gif?raw=true) 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 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 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.wsg.mysigndate" 9 | minSdkVersion 18 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile 'com.android.support:design:23.1.1' 27 | compile 'com.jakewharton:butterknife:7.0.0' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wushaoge/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/wsg/mysigndate/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysigndate; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/CN.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 中文的默认实现类 5 | * 如果你想实现更多的语言请参考Language{@link DPLManager} 6 | * 7 | * The implementation class of chinese. 8 | * You can refer to Language{@link DPLManager} if you want to define more language. 9 | * 10 | * @author AigeStudio 2015-03-28 11 | */ 12 | public class CN extends DPLManager { 13 | @Override 14 | public String[] titleMonth() { 15 | return new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"}; 16 | } 17 | 18 | @Override 19 | public String titleEnsure() { 20 | return "确定"; 21 | } 22 | 23 | @Override 24 | public String titleBC() { 25 | return "公元前"; 26 | } 27 | 28 | @Override 29 | public String[] titleWeek() { 30 | return new String[]{"日", "一", "二", "三", "四", "五", "六"}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPBaseTheme.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 主题的默认实现类 5 | * 6 | * The default implement of theme 7 | * 8 | * @author AigeStudio 2015-06-17 9 | */ 10 | public class DPBaseTheme extends DPTheme { 11 | @Override 12 | public int colorBG() { 13 | return 0xFFFFFFFF; 14 | } 15 | 16 | @Override 17 | public int colorBGCircle() { 18 | return 0x44000000; 19 | } 20 | 21 | @Override 22 | public int colorTitleBG() { 23 | return 0xFFF37B7A; 24 | } 25 | 26 | @Override 27 | public int colorTitle() { 28 | return 0xEEFFFFFF; 29 | } 30 | 31 | @Override 32 | public int colorToday() { 33 | return 0x88F37B7A; 34 | } 35 | 36 | @Override 37 | public int colorG() { 38 | return 0xEE333333; 39 | } 40 | 41 | @Override 42 | public int colorF() { 43 | return 0xEEC08AA4; 44 | } 45 | 46 | @Override 47 | public int colorWeekend() { 48 | return 0xEEF78082; 49 | } 50 | 51 | @Override 52 | public int colorHoliday() { 53 | return 0x80FED6D6; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPCManager.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | import java.util.Locale; 10 | import java.util.Set; 11 | 12 | 13 | /** 14 | * 日期管理器 15 | * The manager of date picker. 16 | * 17 | * @author AigeStudio 2015-06-12 18 | */ 19 | public final class DPCManager { 20 | private static final HashMap> DATE_CACHE = new HashMap<>(); 21 | 22 | private static final HashMap> DECOR_CACHE_BG = new HashMap<>(); 23 | private static final HashMap> DECOR_CACHE_TL = new HashMap<>(); 24 | private static final HashMap> DECOR_CACHE_T = new HashMap<>(); 25 | private static final HashMap> DECOR_CACHE_TR = new HashMap<>(); 26 | private static final HashMap> DECOR_CACHE_L = new HashMap<>(); 27 | private static final HashMap> DECOR_CACHE_R = new HashMap<>(); 28 | 29 | 30 | private List selDateList = new ArrayList(); //选中的日期只有几号 31 | 32 | public List getSelDateList() { 33 | return selDateList; 34 | } 35 | 36 | 37 | private static DPCManager sManager; 38 | 39 | private DPCalendar c; 40 | 41 | private DPCManager() { 42 | // 默认显示为中文日历 43 | String locale = Locale.getDefault().getCountry().toLowerCase(); 44 | if (locale.equals("cn")) { 45 | initCalendar(new DPCNCalendar()); 46 | } else { 47 | initCalendar(new DPUSCalendar()); 48 | } 49 | } 50 | 51 | /** 52 | * 获取月历管理器 53 | * Get calendar manager 54 | * 55 | * @return 月历管理器 56 | */ 57 | public static DPCManager getInstance() { 58 | if (null == sManager) { 59 | sManager = new DPCManager(); 60 | } 61 | return sManager; 62 | } 63 | 64 | /** 65 | * 初始化日历对象 66 | *

67 | * Initialization Calendar 68 | * 69 | * @param c ... 70 | */ 71 | public void initCalendar(DPCalendar c) { 72 | this.c = c; 73 | } 74 | 75 | /** 76 | * 设置有背景标识物的日期 77 | *

78 | * Set date which has decor of background 79 | * 80 | * @param date 日期列表 List of date 81 | */ 82 | public void setDecorBG(List date) { 83 | setDecor(date, DECOR_CACHE_BG); 84 | } 85 | 86 | /** 87 | * 设置左上角有标识物的日期 88 | *

89 | * Set date which has decor on Top left 90 | * 91 | * @param date 日期列表 List of date 92 | */ 93 | public void setDecorTL(List date) { 94 | setDecor(date, DECOR_CACHE_TL); 95 | } 96 | 97 | /** 98 | * 设置顶部有标识物的日期 99 | *

100 | * Set date which has decor on Top 101 | * 102 | * @param date 日期列表 List of date 103 | */ 104 | public void setDecorT(List date) { 105 | setDecor(date, DECOR_CACHE_T); 106 | } 107 | 108 | /** 109 | * 设置右上角有标识物的日期 110 | *

111 | * Set date which has decor on Top right 112 | * 113 | * @param date 日期列表 List of date 114 | */ 115 | public void setDecorTR(List date) { 116 | setDecor(date, DECOR_CACHE_TR); 117 | } 118 | 119 | /** 120 | * 设置左边有标识物的日期 121 | *

122 | * Set date which has decor on left 123 | * 124 | * @param date 日期列表 List of date 125 | */ 126 | public void setDecorL(List date) { 127 | setDecor(date, DECOR_CACHE_L); 128 | } 129 | 130 | /** 131 | * 设置右上角有标识物的日期 132 | *

133 | * Set date which has decor on right 134 | * 135 | * @param date 日期列表 List of date 136 | */ 137 | public void setDecorR(List date) { 138 | setDecor(date, DECOR_CACHE_R); 139 | } 140 | 141 | /** 142 | * 获取指定年月的日历对象数组 143 | * 144 | * @param year 公历年 145 | * @param month 公历月 146 | * @return 日历对象数组 该数组长度恒为6x7 如果某个下标对应无数据则填充为null 147 | */ 148 | public DPInfo[][] obtainDPInfo(int year, int month) { 149 | HashMap dataOfYear = DATE_CACHE.get(year); 150 | if (null != dataOfYear && dataOfYear.size() != 0) { 151 | DPInfo[][] dataOfMonth = dataOfYear.get(month); 152 | if (dataOfMonth != null) { 153 | return dataOfMonth; 154 | } 155 | dataOfMonth = buildDPInfo(year, month); 156 | dataOfYear.put(month, dataOfMonth); 157 | return dataOfMonth; 158 | } 159 | if (null == dataOfYear) dataOfYear = new HashMap<>(); 160 | DPInfo[][] dataOfMonth = buildDPInfo(year, month); 161 | dataOfYear.put((month), dataOfMonth); 162 | DATE_CACHE.put(year, dataOfYear); 163 | return dataOfMonth; 164 | } 165 | 166 | private void setDecor(List date, HashMap> cache) { 167 | for (String str : date) { 168 | int index = str.lastIndexOf("-"); 169 | String key = str.substring(0, index).replace("-", ":"); 170 | Set days = cache.get(key); 171 | if (null == days) { 172 | days = new HashSet<>(); 173 | } 174 | days.add(str.substring(index + 1, str.length())); 175 | cache.put(key, days); 176 | 177 | String tempStr = str.substring(index + 1, str.length()); 178 | 179 | selDateList.add(tempStr); 180 | } 181 | } 182 | 183 | private DPInfo[][] buildDPInfo(int year, int month) { 184 | DPInfo[][] info = new DPInfo[6][7]; 185 | 186 | String[][] strG = c.buildMonthG(year, month); 187 | String[][] strF = c.buildMonthFestival(year, month); 188 | 189 | Set strHoliday = c.buildMonthHoliday(year, month); 190 | Set strWeekend = c.buildMonthWeekend(year, month); 191 | 192 | Set decorBG = DECOR_CACHE_BG.get(year + ":" + month); 193 | Set decorTL = DECOR_CACHE_TL.get(year + ":" + month); 194 | Set decorT = DECOR_CACHE_T.get(year + ":" + month); 195 | Set decorTR = DECOR_CACHE_TR.get(year + ":" + month); 196 | Set decorL = DECOR_CACHE_L.get(year + ":" + month); 197 | Set decorR = DECOR_CACHE_R.get(year + ":" + month); 198 | for (int i = 0; i < info.length; i++) { 199 | for (int j = 0; j < info[i].length; j++) { 200 | DPInfo tmp = new DPInfo(); 201 | tmp.strG = strG[i][j]; 202 | if (c instanceof DPCNCalendar) { 203 | tmp.strF = strF[i][j].replace("F", ""); 204 | } else { 205 | tmp.strF = strF[i][j]; 206 | } 207 | if (!TextUtils.isEmpty(tmp.strG) && strHoliday.contains(tmp.strG)) 208 | tmp.isHoliday = true; 209 | if (!TextUtils.isEmpty(tmp.strG)) tmp.isToday = 210 | c.isToday(year, month, Integer.valueOf(tmp.strG)); 211 | if (strWeekend.contains(tmp.strG)) tmp.isWeekend = true; 212 | if (c instanceof DPCNCalendar) { 213 | if (!TextUtils.isEmpty(tmp.strG)) tmp.isSolarTerms = 214 | ((DPCNCalendar) c).isSolarTerm(year, month, Integer.valueOf(tmp.strG)); 215 | if (!TextUtils.isEmpty(strF[i][j]) && strF[i][j].endsWith("F")) 216 | tmp.isFestival = true; 217 | if (!TextUtils.isEmpty(tmp.strG)) 218 | tmp.isDeferred = ((DPCNCalendar) c) 219 | .isDeferred(year, month, Integer.valueOf(tmp.strG)); 220 | } else { 221 | tmp.isFestival = !TextUtils.isEmpty(strF[i][j]); 222 | } 223 | if (null != decorBG && decorBG.contains(tmp.strG)) tmp.isDecorBG = true; 224 | if (null != decorTL && decorTL.contains(tmp.strG)) tmp.isDecorTL = true; 225 | if (null != decorT && decorT.contains(tmp.strG)) tmp.isDecorT = true; 226 | if (null != decorTR && decorTR.contains(tmp.strG)) tmp.isDecorTR = true; 227 | if (null != decorL && decorL.contains(tmp.strG)) tmp.isDecorL = true; 228 | if (null != decorR && decorR.contains(tmp.strG)) tmp.isDecorR = true; 229 | info[i][j] = tmp; 230 | } 231 | } 232 | return info; 233 | } 234 | 235 | public void clearnDATE_CACHE(){ 236 | DATE_CACHE.clear(); 237 | DECOR_CACHE_BG.clear(); 238 | DECOR_CACHE_TL.clear(); 239 | DECOR_CACHE_T.clear(); 240 | DECOR_CACHE_TR.clear(); 241 | DECOR_CACHE_L.clear(); 242 | DECOR_CACHE_R.clear(); 243 | selDateList.clear(); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPCNCalendar.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | /** 11 | * 中国月历 12 | * 13 | * Calendar of China 14 | * 15 | * @author AigeStudio 2015-06-16 16 | */ 17 | public class DPCNCalendar extends DPCalendar { 18 | private static final int[] FIRST_DAY_OF_LUNAR_IN_GREGORIAN = {1897, 0x75aa, 0x156a, 0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4, 0x135a, 0x495d, 0x95c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8, 0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a, 0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94, 0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a, 0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b, 0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57, 0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae, 0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d, 0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da, 0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4, 0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65, 0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a, 0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694, 0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526, 0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c, 0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a, 0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936, 0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e, 0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c, 0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4, 0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa, 0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa, 0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54, 0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4, 0xfb52}; 19 | 20 | private static final int[] DAYS_AND_LEAP_MONTH_OF_LUNAR = {1897, 0xed436, 0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244, 0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052, 0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41, 0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d, 0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a, 0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848, 0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636, 0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443, 0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f, 0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e, 0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b, 0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39, 0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46, 0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853, 0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641, 0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e, 0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c, 0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a, 0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37, 0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44, 0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51, 0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841, 0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438, 0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051, 0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b, 0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845, 0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d, 0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038, 0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f, 0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849, 0x106a3d}; 21 | 22 | private static final String[] NUMBER_CAPITAL = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"}; 23 | 24 | private static final String[] LUNAR_HEADER = {"初", "十", "廿", "卅", "正", "腊", "冬", "闰"}; 25 | 26 | private static final String[][] FESTIVAL_G = { 27 | {"元旦"}, 28 | {"世界湿地日", "情人节"}, 29 | {"全国爱耳日", "青年志愿者服务日", "国际妇女节", "保护母亲河日", "中国植树节", "白色情人节&国际警察日", "世界消费者权益日", "世界森林日&世界睡眠日", "世界水日", "世界气象日", "世界防治结核病日"}, 30 | {"愚人节", "清明节", "世界卫生日", "世界地球日", "世界知识产权日"}, 31 | {"国际劳动节", "世界哮喘日", "中国青年节", "世界红十字日", "国际护士节", "国际家庭日", "世界电信日", "全国学生营养日", "国际生物多样性日", "国际牛奶日", "世界无烟日"}, 32 | {"国际儿童节", "世界环境日", "全国爱眼日", "世界防治荒漠化日", "国际奥林匹克日", "全国土地日", "国际禁毒日"}, 33 | {"中国共产党诞生日&国际建筑日", "中国抗战纪念日", "世界人口日"}, 34 | {"中国解放军建军节", "国际青年节"}, 35 | {"抗战胜利日", "国际扫盲日", "中国教师节", "中国脑健康日&臭氧层保护日", "全国爱牙日", "世界停火日", "世界旅游日"}, 36 | {"国庆节&国际老年人日", "世界动物日", "世界教师日", "全国高血压日", "世界邮政日", "世界精神卫生日", "世界标准日", "国际盲人节&世界农村妇女日", "世界粮食日", "国际消除贫困日", "联合国日&世界发展新闻日", "中国男性健康日", "万圣节"}, 37 | {"中国记者节", "消防宣传日", "世界糖尿病日", "国际大学生节", "消除对妇女暴力日"}, 38 | {"世界爱滋病日", "世界残疾人日", "全国法制宣传日", "世界足球日", "圣诞节"}}; 39 | 40 | private static final int[][] FESTIVAL_G_DATE = { 41 | {1}, 42 | {2, 14}, 43 | {3, 5, 8, 9, 12, 14, 15, 21, 22, 23, 24}, 44 | {1, 5, 7, 22, 26}, 45 | {1, 3, 4, 8, 12, 15, 17, 20, 22, 23, 31}, 46 | {1, 5, 6, 17, 23, 25, 26}, 47 | {1, 7, 11}, 48 | {1, 12}, 49 | {3, 8, 10, 16, 20, 21, 27}, 50 | {1, 4, 5, 8, 9, 10, 14, 15, 16, 17, 24, 29, 31}, 51 | {8, 9, 14, 17, 25}, 52 | {1, 3, 4, 9, 25}}; 53 | 54 | private static final String[][] FESTIVAL_L = {{"春节", "元宵节"}, 55 | {}, 56 | {}, 57 | {}, 58 | {"端午节"}, 59 | {}, 60 | {"乞巧节"}, 61 | {"中秋节"}, 62 | {"重阳节"}, 63 | {}, 64 | {}, 65 | {"腊八节", "扫房日"}}; 66 | 67 | private static final int[][] FESTIVAL_L_DATE = { 68 | {1, 15}, 69 | {}, 70 | {}, 71 | {}, 72 | {5}, 73 | {}, 74 | {7}, 75 | {15}, 76 | {9}, 77 | {}, 78 | {}, 79 | {8, 24}}; 80 | 81 | private static final String[][] HOLIDAY = {{"1", "2", "3"}, {"18", "19", "20", "21", "22", "23", "24"}, {""}, {"4", "5", "6"}, {"1", "2", "3"}, {"20", "21", "22"}, {""}, {""}, {"3", "4", "5", "26", "27"}, {"1", "2", "3", "4", "5", "6", "7"}, {""}, {""}}; 82 | 83 | private static final String[][] DEFERRED = {{"4"}, {"15", "16", "17", "25", "26", "27", "28"}, {""}, {""}, {""}, {""}, {""}, {""}, {"6", "28", "29", "30"}, {"8", "9", "10"}, {""}, {""}}; 84 | 85 | private static final String SOLAR_TERM[][] = {{"小寒", "大寒"}, {"立春", "雨水"}, {"惊蛰", "春分"}, {"清明", "谷雨"}, {"立夏", "小满"}, {"芒种", "夏至"}, {"小暑", "大暑"}, {"立秋", "处暑"}, {"白露", "秋分"}, {"寒露", "霜降"}, {"立冬", "小雪"}, {"大雪", "冬至"}}; 86 | 87 | private final HashMap CACHE_SOLAR_TERM = new HashMap<>(); 88 | 89 | private SolarTerm mSolarTerm = new SolarTerm(); 90 | 91 | private class G { 92 | int d; 93 | int m; 94 | int y; 95 | } 96 | 97 | private class L { 98 | int d; 99 | int m; 100 | int y; 101 | 102 | boolean isLeap; 103 | } 104 | 105 | @Override 106 | public String[][] buildMonthFestival(int year, int month) { 107 | return buildMonthL(year, month); 108 | } 109 | 110 | @Override 111 | public Set buildMonthHoliday(int year, int month) { 112 | Set tmp = new HashSet<>(); 113 | if (year == 2015) { 114 | Collections.addAll(tmp, HOLIDAY[month - 1]); 115 | } 116 | return tmp; 117 | } 118 | 119 | private String[][] buildMonthL(int year, int month) { 120 | String[][] gregorianMonth = buildMonthG(year, month); 121 | G g = new G(); 122 | String tmp[][] = new String[6][7]; 123 | for (int i = 0; i < tmp.length; i++) { 124 | for (int j = 0; j < tmp[0].length; j++) { 125 | tmp[i][j] = ""; 126 | if (!TextUtils.isEmpty(gregorianMonth[i][j])) { 127 | g.y = year; 128 | g.m = month; 129 | g.d = Integer.valueOf(gregorianMonth[i][j]); 130 | L l = null; 131 | String result = ""; 132 | if (year >= 1900 && year <= 2100) { 133 | l = GTL(g); 134 | result = getFestivalL(l.m, l.d); 135 | } 136 | if (TextUtils.isEmpty(result)) { 137 | result = getFestivalG(g.m, g.d); 138 | if (TextUtils.isEmpty(result)) { 139 | result = getSolarTerm(year, month, g.d); 140 | if (null != l && TextUtils.isEmpty(result)) { 141 | char[] c = String.valueOf(l.d).toCharArray(); 142 | tmp[i][j] = lNumToStr(c); 143 | } else { 144 | tmp[i][j] = result; 145 | } 146 | } else { 147 | tmp[i][j] = result + "F"; 148 | } 149 | } else { 150 | tmp[i][j] = result + "F"; 151 | } 152 | } 153 | } 154 | } 155 | return tmp; 156 | } 157 | 158 | /** 159 | * 判断某年某月某日是否为节气 160 | * 161 | * @param year 公历年 162 | * @param month 公历月 163 | * @param day 公历日 164 | * @return ... 165 | */ 166 | public boolean isSolarTerm(int year, int month, int day) { 167 | return null == getSolarTerm(year, month, day); 168 | } 169 | 170 | /** 171 | * 判断某月某日是否为补休 172 | * 173 | * @param year 公历年 174 | * @param month 公历月 175 | * @param day 公历日 176 | * @return ... 177 | */ 178 | public boolean isDeferred(int year, int month, int day) { 179 | if (year == 2015) { 180 | String[] deferredOfMonth = DEFERRED[month - 1]; 181 | for (String s : deferredOfMonth) { 182 | if (!TextUtils.isEmpty(s) && Integer.valueOf(s) == day) return true; 183 | } 184 | } 185 | return false; 186 | } 187 | 188 | private String getSolarTerm(int year, int month, int day) { 189 | String[][] tmp = CACHE_SOLAR_TERM.get(year); 190 | if (null == tmp) { 191 | tmp = mSolarTerm.buildSolarTerm(year); 192 | CACHE_SOLAR_TERM.put(year, tmp); 193 | } 194 | String[] STOfMonth = tmp[month - 1]; 195 | if (Integer.valueOf(STOfMonth[0]) == day) { 196 | return SOLAR_TERM[month - 1][0]; 197 | } else if (Integer.valueOf(STOfMonth[1]) == day) { 198 | return SOLAR_TERM[month - 1][1]; 199 | } 200 | return ""; 201 | } 202 | 203 | private String getFestivalL(int month, int day) { 204 | String tmp = ""; 205 | int[] daysInMonth = FESTIVAL_L_DATE[month - 1]; 206 | for (int i = 0; i < daysInMonth.length; i++) { 207 | if (day == daysInMonth[i]) { 208 | tmp = FESTIVAL_L[month - 1][i]; 209 | } 210 | } 211 | return tmp; 212 | } 213 | 214 | private String getFestivalG(int month, int day) { 215 | String tmp = ""; 216 | int[] daysInMonth = FESTIVAL_G_DATE[month - 1]; 217 | for (int i = 0; i < daysInMonth.length; i++) { 218 | if (day == daysInMonth[i]) { 219 | tmp = FESTIVAL_G[month - 1][i]; 220 | } 221 | } 222 | return tmp; 223 | } 224 | 225 | private L GTL(G g) { 226 | int index = g.y - DAYS_AND_LEAP_MONTH_OF_LUNAR[0]; 227 | int data = (g.y << 9) | (g.m << 5) | (g.d); 228 | int lunarFirstDayInGregorian; 229 | if (DAYS_AND_LEAP_MONTH_OF_LUNAR[index] > data) { 230 | index--; 231 | } 232 | lunarFirstDayInGregorian = DAYS_AND_LEAP_MONTH_OF_LUNAR[index]; 233 | 234 | int y = getBitInt(lunarFirstDayInGregorian, 12, 9); 235 | int m = getBitInt(lunarFirstDayInGregorian, 4, 5); 236 | int d = getBitInt(lunarFirstDayInGregorian, 5, 0); 237 | 238 | long offset = GToNum(g.y, g.m, g.d) - GToNum(y, m, d); 239 | int days = FIRST_DAY_OF_LUNAR_IN_GREGORIAN[index]; 240 | int leap = getBitInt(days, 4, 13); 241 | 242 | int lunarY = index + DAYS_AND_LEAP_MONTH_OF_LUNAR[0]; 243 | int lunarM = 1; 244 | int lunarD; 245 | offset += 1; 246 | 247 | for (int i = 0; i < 13; i++) { 248 | int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29; 249 | if (offset > dm) { 250 | lunarM++; 251 | offset -= dm; 252 | } else { 253 | break; 254 | } 255 | } 256 | lunarD = (int) (offset); 257 | L l = new L(); 258 | l.y = lunarY; 259 | l.m = lunarM; 260 | l.isLeap = false; 261 | if (leap != 0 && lunarM > leap) { 262 | l.m = lunarM - 1; 263 | if (lunarM == leap + 1) { 264 | l.isLeap = true; 265 | } 266 | } 267 | l.d = lunarD; 268 | return l; 269 | } 270 | 271 | private String lNumToStr(char[] c) { 272 | String result = ""; 273 | if (c.length == 1) { 274 | for (int i = 1; i < 10; i++) { 275 | if (c[0] == String.valueOf(i).charAt(0)) { 276 | result = LUNAR_HEADER[0] + NUMBER_CAPITAL[i]; 277 | } 278 | } 279 | } else { 280 | if (c[0] == '1') { 281 | if (c[1] == '0') { 282 | result = LUNAR_HEADER[0] + LUNAR_HEADER[1]; 283 | } else { 284 | for (int i = 1; i < 10; i++) { 285 | if (c[1] == String.valueOf(i).charAt(0)) { 286 | result = LUNAR_HEADER[1] + NUMBER_CAPITAL[i]; 287 | } 288 | } 289 | } 290 | } else if (c[0] == '2') { 291 | if (c[1] == '0') { 292 | result = LUNAR_HEADER[2] + LUNAR_HEADER[1]; 293 | } else { 294 | for (int i = 1; i < 10; i++) { 295 | if (c[1] == String.valueOf(i).charAt(0)) { 296 | result = LUNAR_HEADER[2] + NUMBER_CAPITAL[i]; 297 | } 298 | } 299 | } 300 | } else { 301 | if (c[1] == '0') { 302 | result = LUNAR_HEADER[3] + LUNAR_HEADER[1]; 303 | } else { 304 | for (int i = 1; i < 10; i++) { 305 | if (c[1] == String.valueOf(i).charAt(0)) { 306 | result = LUNAR_HEADER[3] + NUMBER_CAPITAL[i]; 307 | } 308 | } 309 | } 310 | } 311 | } 312 | return result; 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPCNTheme.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 天朝日历主题类 5 | * 其他国家的主题不需要这样去处理 6 | * 7 | * Theme of china 8 | * You don't need this class for other countries 9 | * 10 | * @author AigeStudio 2015-06-17 11 | */ 12 | public class DPCNTheme extends DPBaseTheme { 13 | /** 14 | * 农历文本颜色 15 | * 16 | * Color of Lunar text 17 | * 18 | * @return 16进制颜色值 hex color 19 | */ 20 | public int colorL() { 21 | return 0xEE888888; 22 | } 23 | 24 | /** 25 | * 补休日期背景颜色 26 | * 27 | * Color of Deferred background 28 | * 29 | * @return 16进制颜色值 hex color 30 | */ 31 | public int colorDeferred() { 32 | return 0x50B48172; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPCalendar.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import java.util.Calendar; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | /** 8 | * 月历抽象父类 9 | * 继承该类可以实现自己的日历对象 10 | *

11 | * Abstract class of Calendar 12 | * 13 | * @author AigeStudio 2015-06-15 14 | */ 15 | public abstract class DPCalendar { 16 | protected final Calendar c = Calendar.getInstance(); 17 | 18 | /** 19 | * 获取某年某月的节日数组 20 | *

21 | * Build the festival date array of given year and month 22 | * 23 | * @param year 某年 24 | * @param month 某月 25 | * @return 该月节日数组 26 | */ 27 | public abstract String[][] buildMonthFestival(int year, int month); 28 | 29 | /** 30 | * 获取某年某月的假期数组 31 | *

32 | * Build the holiday date array of given year and month 33 | * 34 | * @param year 某年 35 | * @param month 某月 36 | * @return 该月假期数组 37 | */ 38 | public abstract Set buildMonthHoliday(int year, int month); 39 | 40 | /** 41 | * 判断某年是否为闰年 42 | * 43 | * @param year ... 44 | * @return true表示闰年 45 | */ 46 | public boolean isLeapYear(int year) { 47 | return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)); 48 | } 49 | 50 | /** 51 | * 判断给定日期是否为今天 52 | * 53 | * @param year 某年 54 | * @param month 某月 55 | * @param day 某天 56 | * @return ... 57 | */ 58 | public boolean isToday(int year, int month, int day) { 59 | Calendar c1 = Calendar.getInstance(); 60 | Calendar c2 = Calendar.getInstance(); 61 | c1.set(year, month - 1, day); 62 | return (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)) && 63 | (c1.get(Calendar.MONTH) == (c2.get(Calendar.MONTH))) && 64 | (c1.get(Calendar.DAY_OF_MONTH) == c2.get(Calendar.DAY_OF_MONTH)); 65 | } 66 | 67 | /** 68 | * 生成某年某月的公历天数数组 69 | * 数组为6x7的二维数组因为一个月的周数永远不会超过六周 70 | * 天数填充对应相应的二维数组下标 71 | * 如果某个数组下标中没有对应天数那么则填充一个空字符串 72 | * 73 | * @param year 某年 74 | * @param month 某月 75 | * @return 某年某月的公历天数数组 76 | */ 77 | public String[][] buildMonthG(int year, int month) { 78 | c.clear(); 79 | String tmp[][] = new String[6][7]; 80 | c.set(year, month - 1, 1); 81 | 82 | int daysInMonth = 0; 83 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || 84 | month == 12) { 85 | daysInMonth = 31; 86 | } else if (month == 4 || month == 6 || month == 9 || month == 11) { 87 | daysInMonth = 30; 88 | } else if (month == 2) { 89 | if (isLeapYear(year)) { 90 | daysInMonth = 29; 91 | } else { 92 | daysInMonth = 28; 93 | } 94 | } 95 | int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY; 96 | int day = 1; 97 | for (int i = 0; i < 6; i++) { 98 | for (int j = 0; j < 7; j++) { 99 | tmp[i][j] = ""; 100 | if (i == 0 && j >= dayOfWeek) { 101 | tmp[i][j] = "" + day; 102 | day++; 103 | } else if (i > 0 && day <= daysInMonth) { 104 | tmp[i][j] = "" + day; 105 | day++; 106 | } 107 | } 108 | } 109 | return tmp; 110 | } 111 | 112 | /** 113 | * 生成某年某月的周末日期集合 114 | * 115 | * @param year 某年 116 | * @param month 某月 117 | * @return 某年某月的周末日期集合 118 | */ 119 | public Set buildMonthWeekend(int year, int month) { 120 | Set set = new HashSet<>(); 121 | c.clear(); 122 | c.set(year, month - 1, 1); 123 | do { 124 | int day = c.get(Calendar.DAY_OF_WEEK); 125 | if (day == Calendar.SATURDAY || day == Calendar.SUNDAY) { 126 | set.add(String.valueOf(c.get(Calendar.DAY_OF_MONTH))); 127 | } 128 | c.add(Calendar.DAY_OF_YEAR, 1); 129 | } while (c.get(Calendar.MONTH) == month - 1); 130 | return set; 131 | } 132 | 133 | protected long GToNum(int year, int month, int day) { 134 | month = (month + 9) % 12; 135 | year = year - month / 10; 136 | return 365 * year + year / 4 - year / 100 + year / 400 + (month * 306 + 5) / 10 + (day - 1); 137 | } 138 | 139 | protected int getBitInt(int data, int length, int shift) { 140 | return (data & (((1 << length) - 1) << shift)) >> shift; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPDecor.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.Rect; 6 | 7 | /** 8 | * 月历装饰物类 9 | * Decor of Calendar 10 | * 11 | * @author AigeStudio 2015-07-22 12 | * @author AigeStudio 2015-10-29 13 | * 为每一个装饰物的绘制方法增加一个含参data的重载方法 14 | * Add a parameter for each method. 15 | */ 16 | public class DPDecor { 17 | /** 18 | * 绘制当前日期区域左上角的装饰物 19 | * Draw decor on Top left of current date area 20 | * 21 | * @param canvas 绘制图形的画布 Canvas of image drew 22 | * @param rect 可以绘制的区域范围 Area you can draw 23 | * @param paint 画笔对象 Paint 24 | * @param data 日期 25 | */ 26 | public void drawDecorTL(Canvas canvas, Rect rect, Paint paint, String data) { 27 | drawDecorTL(canvas, rect, paint); 28 | } 29 | 30 | /** 31 | * @see #drawDecorTL(Canvas, Rect, Paint, String) 32 | */ 33 | public void drawDecorTL(Canvas canvas, Rect rect, Paint paint) { 34 | 35 | } 36 | 37 | /** 38 | * 绘制当前日期区域顶部的装饰物 39 | * Draw decor on top of current date area 40 | * 41 | * @param canvas 绘制图形的画布 Canvas of image drew 42 | * @param rect 可以绘制的区域范围 Area you can draw 43 | * @param paint 画笔对象 Paint 44 | * @param data 日期 45 | */ 46 | public void drawDecorT(Canvas canvas, Rect rect, Paint paint, String data) { 47 | drawDecorT(canvas, rect, paint); 48 | } 49 | 50 | /** 51 | * @see #drawDecorT(Canvas, Rect, Paint, String) 52 | */ 53 | public void drawDecorT(Canvas canvas, Rect rect, Paint paint) { 54 | 55 | } 56 | 57 | /** 58 | * 绘制当前日期区域右上角的装饰物 59 | * Draw decor on Top right of current date area 60 | * 61 | * @param canvas 绘制图形的画布 Canvas of image drew 62 | * @param rect 可以绘制的区域范围 Area you can draw 63 | * @param paint 画笔对象 Paint 64 | * @param data 日期 65 | */ 66 | public void drawDecorTR(Canvas canvas, Rect rect, Paint paint, String data) { 67 | drawDecorTR(canvas, rect, paint); 68 | } 69 | 70 | /** 71 | * @see #drawDecorTR(Canvas, Rect, Paint, String) 72 | */ 73 | public void drawDecorTR(Canvas canvas, Rect rect, Paint paint) { 74 | 75 | } 76 | 77 | /** 78 | * 绘制当前日期区域左边的装饰物 79 | * Draw decor on left of current date area 80 | * 81 | * @param canvas 绘制图形的画布 Canvas of image drew 82 | * @param rect 可以绘制的区域范围 Area you can draw 83 | * @param paint 画笔对象 Paint 84 | * @param data 日期 85 | */ 86 | public void drawDecorL(Canvas canvas, Rect rect, Paint paint, String data) { 87 | drawDecorL(canvas, rect, paint); 88 | } 89 | 90 | /** 91 | * @see #drawDecorL(Canvas, Rect, Paint, String) 92 | */ 93 | public void drawDecorL(Canvas canvas, Rect rect, Paint paint) { 94 | 95 | } 96 | 97 | /** 98 | * 绘制当前日期区域右边的装饰物 99 | * Draw decor on right of current date area 100 | * 101 | * @param canvas 绘制图形的画布 Canvas of image drew 102 | * @param rect 可以绘制的区域范围 Area you can draw 103 | * @param paint 画笔对象 Paint 104 | * @param data 日期 105 | */ 106 | public void drawDecorR(Canvas canvas, Rect rect, Paint paint, String data) { 107 | drawDecorR(canvas, rect, paint); 108 | } 109 | 110 | /** 111 | * @see #drawDecorR(Canvas, Rect, Paint, String) 112 | */ 113 | public void drawDecorR(Canvas canvas, Rect rect, Paint paint) { 114 | 115 | } 116 | 117 | /** 118 | * 绘制当前日期区域背景的装饰物 119 | * Draw decor of background of current date area 120 | * 121 | * @param canvas 绘制图形的画布 Canvas of image drew 122 | * @param rect 可以绘制的区域范围 Area you can draw 123 | * @param paint 画笔对象 Paint 124 | * @param data 日期 125 | */ 126 | public void drawDecorBG(Canvas canvas, Rect rect, Paint paint, String data) { 127 | drawDecorBG(canvas, rect, paint); 128 | } 129 | 130 | /** 131 | * @see #drawDecorBG(Canvas, Rect, Paint, String) 132 | */ 133 | public void drawDecorBG(Canvas canvas, Rect rect, Paint paint) { 134 | 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPInfo.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 日历数据实体 5 | * 封装日历绘制时需要的数据 6 | * 7 | * Entity of calendar 8 | * 9 | * @author AigeStudio 2015-03-26 10 | */ 11 | public class DPInfo { 12 | public String strG, strF; 13 | public boolean isHoliday; 14 | public boolean isToday, isWeekend; 15 | public boolean isSolarTerms, isFestival, isDeferred; 16 | public boolean isDecorBG; 17 | public boolean isDecorTL, isDecorT, isDecorTR, isDecorL, isDecorR; 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPLManager.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * 语言对象抽象父类 7 | * DatePicker暂且支持中文和英文两种显示语言 8 | * 如果你需要定义更多的语言可以新建自己的语言类并继承Language重写其方法即可 9 | * 同时你需要在Language的单例方法{@link #getInstance()}的分支语句中添加自己的语言类判断 10 | * 11 | * The abstract of language. 12 | * The current language only two support chinese and english in DatePicker. 13 | * If you need more language you want,you can define your own language class and extends Language 14 | * override all method. 15 | * Also you must add a judge of your language in branching statement of single case method{@link #getInstance()} 16 | * 17 | * @author AigeStudio 2015-03-26 18 | */ 19 | public abstract class DPLManager { 20 | private static DPLManager sLanguage; 21 | 22 | /** 23 | * 获取日历语言管理器 24 | * 25 | * Get DatePicker language manager 26 | * 27 | * @return 日历语言管理器 DatePicker language manager 28 | */ 29 | public static DPLManager getInstance() { 30 | if (null == sLanguage) { 31 | String locale = Locale.getDefault().getLanguage().toLowerCase(); 32 | if (locale.equals("zh")) { 33 | sLanguage = new CN(); 34 | } else { 35 | sLanguage = new EN(); 36 | } 37 | } 38 | return sLanguage; 39 | } 40 | 41 | /** 42 | * 月份标题显示 43 | * 44 | * Titles of month 45 | * 46 | * @return 长度为12的月份标题数组 Array in 12 length of month titles 47 | */ 48 | public abstract String[] titleMonth(); 49 | 50 | /** 51 | * 确定按钮文本 52 | * 53 | * Text of ensure button 54 | * 55 | * @return Text of ensure button 56 | */ 57 | public abstract String titleEnsure(); 58 | 59 | /** 60 | * 公元前文本 61 | * 62 | * Text of B.C. 63 | * 64 | * @return Text of B.C. 65 | */ 66 | public abstract String titleBC(); 67 | 68 | /** 69 | * 星期标题显示 70 | * 71 | * Titles of week 72 | * 73 | * @return 长度为7的星期标题数组 Array in 7 length of week titles 74 | */ 75 | public abstract String[] titleWeek(); 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPMode.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 日期选择模式 5 | * 支持单选和多选和展示 6 | * Date select mode 7 | * Support SINGLE or MULTIPLE or Display only. 8 | * 9 | * @author AigeStudio 2015-07-02 10 | */ 11 | public enum DPMode { 12 | SINGLE, MULTIPLE, NONE 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPTManager.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 日历主题管理器 5 | * 在DatePicker被实例化前调用{@link #initCalendar(DPTheme)}方法来初始化一个日历主题对象 6 | * 7 | * DatePicker theme manager 8 | * Call {@link #initCalendar(DPTheme)} method to initialization a theme before DatePicker instance 9 | * 10 | * @author AigeStudio 2015-06-30 11 | */ 12 | public final class DPTManager { 13 | private static DPTManager sManager; 14 | 15 | private DPTheme theme;// 主题对象 16 | 17 | private DPTManager() { 18 | initCalendar(new DPCNTheme()); 19 | } 20 | 21 | /** 22 | * 获取日历主题管理器 23 | * 24 | * Get DatePicker theme manager 25 | * 26 | * @return 日历主题管理器 DatePicker theme manager 27 | */ 28 | public static DPTManager getInstance() { 29 | if (null == sManager) { 30 | sManager = new DPTManager(); 31 | } 32 | return sManager; 33 | } 34 | 35 | /** 36 | * 初始化主题对象 37 | * 38 | * Initialization Theme 39 | * 40 | * @param theme ... 41 | */ 42 | public void initCalendar(DPTheme theme) { 43 | this.theme = theme; 44 | } 45 | 46 | /** 47 | * @see DPTheme#colorTitleBG() 48 | */ 49 | public int colorTitleBG() { 50 | return theme.colorTitleBG(); 51 | } 52 | 53 | /** 54 | * @see DPTheme#colorBG() 55 | */ 56 | public int colorBG() { 57 | return theme.colorBG(); 58 | } 59 | 60 | /** 61 | * @see DPTheme#colorBGCircle() 62 | */ 63 | public int colorBGCircle() { 64 | return theme.colorBGCircle(); 65 | } 66 | 67 | /** 68 | * @see DPTheme#colorTitle() 69 | */ 70 | public int colorTitle() { 71 | return theme.colorTitle(); 72 | } 73 | 74 | /** 75 | * @see DPTheme#colorToday() 76 | */ 77 | public int colorToday() { 78 | return theme.colorToday(); 79 | } 80 | 81 | /** 82 | * @see DPTheme#colorG() 83 | */ 84 | public int colorG() { 85 | return theme.colorG(); 86 | } 87 | 88 | /** 89 | * @see DPTheme#colorF() 90 | */ 91 | public int colorF() { 92 | return theme.colorF(); 93 | } 94 | 95 | /** 96 | * @see DPTheme#colorWeekend() 97 | */ 98 | public int colorWeekend() { 99 | return theme.colorWeekend(); 100 | } 101 | 102 | /** 103 | * @see DPTheme#colorHoliday() 104 | */ 105 | public int colorHoliday() { 106 | return theme.colorHoliday(); 107 | } 108 | 109 | /** 110 | * @see DPCNTheme#colorL() 111 | */ 112 | public int colorL() { 113 | if (theme instanceof DPCNTheme) { 114 | return ((DPCNTheme) theme).colorL(); 115 | } 116 | return 0; 117 | } 118 | 119 | /** 120 | * @see DPCNTheme#colorDeferred() 121 | */ 122 | public int colorDeferred() { 123 | if (theme instanceof DPCNTheme) { 124 | return ((DPCNTheme) theme).colorDeferred(); 125 | } 126 | return 0; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPTheme.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 主题抽象类 5 | * 你可以继承该类定制自己的颜色主题 6 | * 7 | * Abstract class of theme 8 | * You can extends this class to implement your own theme colors 9 | * 10 | * @author AigeStudio 2015-06-30 11 | */ 12 | public abstract class DPTheme { 13 | /** 14 | * 月视图背景色 15 | * 16 | * Color of MonthView's background 17 | * 18 | * @return 16进制颜色值 hex color 19 | */ 20 | public abstract int colorBG(); 21 | 22 | /** 23 | * 背景圆颜色 24 | * 25 | * Color of MonthView's selected circle 26 | * 27 | * @return 16进制颜色值 hex color 28 | */ 29 | public abstract int colorBGCircle(); 30 | 31 | /** 32 | * 标题栏背景色 33 | * 34 | * Color of TitleBar's background 35 | * 36 | * @return 16进制颜色值 hex color 37 | */ 38 | public abstract int colorTitleBG(); 39 | 40 | /** 41 | * 标题栏文本颜色 42 | * 43 | * Color of TitleBar text 44 | * 45 | * @return 16进制颜色值 hex color 46 | */ 47 | public abstract int colorTitle(); 48 | 49 | /** 50 | * 今天的背景色 51 | * 52 | * Color of Today's background 53 | * 54 | * @return 16进制颜色值 hex color 55 | */ 56 | public abstract int colorToday(); 57 | 58 | /** 59 | * 公历文本颜色 60 | * 61 | * Color of Gregorian text 62 | * 63 | * @return 16进制颜色值 hex color 64 | */ 65 | public abstract int colorG(); 66 | 67 | /** 68 | * 节日文本颜色 69 | * 70 | * Color of Festival text 71 | * 72 | * @return 16进制颜色值 hex color 73 | */ 74 | public abstract int colorF(); 75 | 76 | /** 77 | * 周末文本颜色 78 | * 79 | * Color of Weekend text 80 | * 81 | * @return 16进制颜色值 hex color 82 | */ 83 | public abstract int colorWeekend(); 84 | 85 | /** 86 | * 假期文本颜色 87 | * 88 | * Color of Holiday text 89 | * 90 | * @return 16进制颜色值 hex color 91 | */ 92 | public abstract int colorHoliday(); 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DPUSCalendar.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.Collections; 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * 美国月历 11 | * 12 | * Calendar of America 13 | * 14 | * @author AigeStudio 2015-07-22 15 | */ 16 | public class DPUSCalendar extends DPCalendar { 17 | private static final String[][] FESTIVAL_G = { 18 | {"New Year"}, 19 | {"Lincoln's Birthday", "St.Valentine's Day", "Washington's Birthday"}, 20 | {"St.Patrick's Day"}, 21 | {"All Fools' Day"}, 22 | {}, 23 | {"Flag Day"}, 24 | {"Independence Day"}, 25 | {}, 26 | {}, 27 | {"Columbus Day"}, 28 | {"Halloween"}, 29 | {"Christmas"}}; 30 | 31 | private static final int[][] FESTIVAL_G_DATE = { 32 | {1}, 33 | {12, 14, 18}, 34 | {17}, 35 | {1}, 36 | {}, 37 | {14}, 38 | {4}, 39 | {}, 40 | {}, 41 | {12}, 42 | {1}, 43 | {25}}; 44 | private static final String[][] HOLIDAY = {{"1"}, {""}, {""}, {""}, {"24", "25", "26"}, {""}, {"4", "5", "6"}, {"30"}, {"1", "2"}, {""}, {"27", "28", "29", "30"}, {"25", "26", "27"}}; 45 | 46 | @Override 47 | public String[][] buildMonthFestival(int year, int month) { 48 | String[][] gregorianMonth = buildMonthG(year, month); 49 | String tmp[][] = new String[6][7]; 50 | for (int i = 0; i < tmp.length; i++) { 51 | for (int j = 0; j < tmp[0].length; j++) { 52 | tmp[i][j] = ""; 53 | String day = gregorianMonth[i][j]; 54 | if (!TextUtils.isEmpty(day)) { 55 | tmp[i][j] = getFestivalG(month, Integer.valueOf(day)); 56 | } 57 | } 58 | } 59 | return tmp; 60 | } 61 | 62 | @Override 63 | public Set buildMonthHoliday(int year, int month) { 64 | Set tmp = new HashSet<>(); 65 | if (year == 2015) { 66 | Collections.addAll(tmp, HOLIDAY[month - 1]); 67 | } 68 | return tmp; 69 | } 70 | 71 | private String getFestivalG(int month, int day) { 72 | String tmp = ""; 73 | int[] daysInMonth = FESTIVAL_G_DATE[month - 1]; 74 | for (int i = 0; i < daysInMonth.length; i++) { 75 | if (day == daysInMonth[i]) { 76 | tmp = FESTIVAL_G[month - 1][i]; 77 | } 78 | } 79 | return tmp; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DataUtils.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 数组操作工具类 5 | * 6 | * Utils of data operation 7 | * 8 | * @author AigeStudio 2015-07-22 9 | */ 10 | public final class DataUtils { 11 | /** 12 | * 一维数组转换为二维数组 13 | * 14 | * @param src ... 15 | * @param row ... 16 | * @param column ... 17 | * @return ... 18 | */ 19 | public static String[][] arraysConvert(String[] src, int row, int column) { 20 | String[][] tmp = new String[row][column]; 21 | for (int i = 0; i < row; i++) { 22 | tmp[i] = new String[column]; 23 | System.arraycopy(src, i * column, tmp[i], 0, column); 24 | } 25 | return tmp; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DatePicker.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.util.TypedValue; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.widget.LinearLayout; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import com.wsg.mysigndate.R; 13 | 14 | import java.util.List; 15 | 16 | import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 17 | 18 | /** 19 | * 签到的DatePicker 20 | */ 21 | public class DatePicker extends LinearLayout { 22 | private DPTManager mTManager;// 主题管理器 23 | private DPLManager mLManager;// 语言管理器 24 | 25 | private Context mContext; 26 | 27 | private MonthView monthView;// 月视图 28 | // private TextView tvYear, tvMonth;// 年份 月份显示 29 | // private TextView tvEnsure;// 确定按钮显示 30 | 31 | 32 | private TextView myMonth; //左边月份显示 33 | private TextView myTitle; //中间签到文字显示 34 | private RelativeLayout signIn; //右边签到布局 35 | private TextView mySignIn; //签到文字显示 36 | 37 | private boolean isSignIn = false; //是否签到 38 | 39 | private OnClickSignIn onClickSignIn; 40 | 41 | private OnDateSelectedListener onDateSelectedListener;// 日期多选后监听 42 | 43 | /** 44 | * 点击签到触发 45 | */ 46 | public interface OnClickSignIn{ 47 | void signIn(); 48 | } 49 | 50 | /** 51 | * 日期单选监听器 52 | */ 53 | public interface OnDatePickedListener { 54 | void onDatePicked(String date); 55 | } 56 | 57 | /** 58 | * 日期多选监听器 59 | */ 60 | public interface OnDateSelectedListener { 61 | void onDateSelected(List date); 62 | } 63 | 64 | public DatePicker(Context context) { 65 | this(context, null); 66 | } 67 | 68 | public DatePicker(Context context, AttributeSet attrs) { 69 | super(context, attrs); 70 | mTManager = DPTManager.getInstance(); 71 | mLManager = DPLManager.getInstance(); 72 | 73 | mContext = context; 74 | 75 | // 设置排列方向为竖向 76 | setOrientation(VERTICAL); 77 | 78 | LayoutParams llParams = 79 | new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 80 | 81 | // 标题栏根布局 82 | RelativeLayout rlTitle = new RelativeLayout(context); 83 | rlTitle.setBackgroundColor(mTManager.colorTitleBG()); 84 | int rlTitlePadding = MeasureUtil.dp2px(context, 10); 85 | rlTitle.setPadding(rlTitlePadding, rlTitlePadding, rlTitlePadding, rlTitlePadding); 86 | 87 | // 周视图根布局 88 | LinearLayout llWeek = new LinearLayout(context); 89 | llWeek.setBackgroundColor(mTManager.colorTitleBG()); 90 | llWeek.setOrientation(HORIZONTAL); 91 | int llWeekPadding = MeasureUtil.dp2px(context, 5); 92 | llWeek.setPadding(0, llWeekPadding, 0, llWeekPadding); 93 | LayoutParams lpWeek = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 94 | lpWeek.weight = 1; 95 | 96 | // 标题栏子元素布局参数 97 | // RelativeLayout.LayoutParams lpYear = 98 | // new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 99 | // lpYear.addRule(RelativeLayout.CENTER_VERTICAL); 100 | // RelativeLayout.LayoutParams lpMonth = 101 | // new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 102 | // lpMonth.addRule(RelativeLayout.CENTER_IN_PARENT); 103 | // RelativeLayout.LayoutParams lpEnsure = 104 | // new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 105 | // lpEnsure.addRule(RelativeLayout.CENTER_VERTICAL); 106 | // lpEnsure.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 107 | 108 | // --------------------------------------------------------------------------------标题栏 109 | // 年份显示 110 | // tvYear = new TextView(context); 111 | // tvYear.setText("2015"); 112 | // tvYear.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 113 | // tvYear.setTextColor(mTManager.colorTitle()); 114 | // 115 | // // 月份显示 116 | // tvMonth = new TextView(context); 117 | // tvMonth.setText("六月"); 118 | // tvMonth.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); 119 | // tvMonth.setTextColor(mTManager.colorTitle()); 120 | // 121 | // // 确定显示 122 | // tvEnsure = new TextView(context); 123 | // tvEnsure.setText(mLManager.titleEnsure()); 124 | // tvEnsure.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 125 | // tvEnsure.setTextColor(mTManager.colorTitle()); 126 | // tvEnsure.setOnClickListener(new OnClickListener() { 127 | // @Override 128 | // public void onClick(View v) { 129 | // if (null != onDateSelectedListener) { 130 | // onDateSelectedListener.onDateSelected(monthView.getDateSelected()); 131 | // } 132 | // } 133 | // }); 134 | // 135 | // rlTitle.addView(tvYear, lpYear); 136 | // rlTitle.addView(tvMonth, lpMonth); 137 | // rlTitle.addView(tvEnsure, lpEnsure); 138 | 139 | 140 | RelativeLayout.LayoutParams lpMyMonth = 141 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 142 | lpMyMonth.addRule(RelativeLayout.CENTER_VERTICAL); 143 | RelativeLayout.LayoutParams lpMyTitle = 144 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 145 | lpMyTitle.addRule(RelativeLayout.CENTER_IN_PARENT); 146 | RelativeLayout.LayoutParams lpSignIn = 147 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 148 | lpSignIn.addRule(RelativeLayout.CENTER_VERTICAL); 149 | lpSignIn.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 150 | RelativeLayout.LayoutParams lpTvSignIn = 151 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 152 | lpTvSignIn.addRule(RelativeLayout.CENTER_VERTICAL); 153 | 154 | 155 | myMonth = new TextView(context); 156 | myMonth.setText("1月"); 157 | myMonth.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 158 | myMonth.setTextColor(mTManager.colorTitle()); 159 | 160 | myTitle = new TextView(context); 161 | myTitle.setText("已经连续签到8天"); 162 | myTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 163 | myTitle.setTextColor(mTManager.colorTitle()); 164 | 165 | 166 | signIn = new RelativeLayout(context); 167 | signIn.setPadding(rlTitlePadding, rlTitlePadding, rlTitlePadding, rlTitlePadding); 168 | //signIn.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.box_gray_solid)); 169 | 170 | mySignIn = new TextView(context); 171 | //mySignIn.setText("已签到"); 172 | mySignIn.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 173 | mySignIn.setTextColor(mTManager.colorTitle()); 174 | 175 | signIn.addView(mySignIn, lpTvSignIn); 176 | 177 | setRightTitle(isSignIn); 178 | 179 | signIn.setOnClickListener(new OnClickListener() { 180 | @Override 181 | public void onClick(View v) { 182 | if (!isSignIn) { 183 | onClickSignIn.signIn(); 184 | } 185 | } 186 | }); 187 | 188 | 189 | rlTitle.addView(myMonth, lpMyMonth); 190 | // rlTitle.addView(myTitle, lpMyTitle); 191 | rlTitle.addView(signIn, lpSignIn); 192 | 193 | 194 | addView(rlTitle, llParams); 195 | 196 | // --------------------------------------------------------------------------------周视图 197 | for (int i = 0; i < mLManager.titleWeek().length; i++) { 198 | TextView tvWeek = new TextView(context); 199 | tvWeek.setText(mLManager.titleWeek()[i]); 200 | tvWeek.setGravity(Gravity.CENTER); 201 | tvWeek.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); 202 | tvWeek.setTextColor(mTManager.colorTitle()); 203 | llWeek.addView(tvWeek, lpWeek); 204 | } 205 | addView(llWeek, llParams); 206 | 207 | // ------------------------------------------------------------------------------------月视图 208 | monthView = new MonthView(context); 209 | monthView.setOnDateChangeListener(new MonthView.OnDateChangeListener() { 210 | @Override 211 | public void onMonthChange(int month) { 212 | //tvMonth.setText(mLManager.titleMonth()[month - 1]); 213 | } 214 | 215 | @Override 216 | public void onYearChange(int year) { 217 | String tmp = String.valueOf(year); 218 | if (tmp.startsWith("-")) { 219 | tmp = tmp.replace("-", mLManager.titleBC()); 220 | } 221 | //tvYear.setText(tmp); 222 | } 223 | 224 | @Override 225 | public void onAllChange(int year, int month) { 226 | 227 | } 228 | }); 229 | addView(monthView, llParams); 230 | } 231 | 232 | /** 233 | * 设置初始化年月日期 234 | * 235 | * @param year ... 236 | * @param month ... 237 | */ 238 | public void setDate(int year, int month) { 239 | if (month < 1) { 240 | month = 1; 241 | } 242 | if (month > 12) { 243 | month = 12; 244 | } 245 | monthView.setDate(year, month); 246 | } 247 | 248 | public void setDPDecor(DPDecor decor) { 249 | monthView.setDPDecor(decor); 250 | } 251 | 252 | /** 253 | * 设置日期选择模式 254 | * 255 | * @param mode ... 256 | */ 257 | public void setMode(DPMode mode) { 258 | if (mode != DPMode.MULTIPLE) { 259 | //tvEnsure.setVisibility(GONE); 260 | } 261 | monthView.setDPMode(mode); 262 | } 263 | 264 | /** 265 | * 节日标识 266 | * @param isFestivalDisplay 267 | */ 268 | public void setFestivalDisplay(boolean isFestivalDisplay) { 269 | monthView.setFestivalDisplay(isFestivalDisplay); 270 | } 271 | 272 | /** 273 | * 今天标识 274 | * @param isTodayDisplay 275 | */ 276 | public void setTodayDisplay(boolean isTodayDisplay) { 277 | monthView.setTodayDisplay(isTodayDisplay); 278 | } 279 | 280 | /** 281 | * 假期标识 282 | * @param isHolidayDisplay 283 | */ 284 | public void setHolidayDisplay(boolean isHolidayDisplay) { 285 | monthView.setHolidayDisplay(isHolidayDisplay); 286 | } 287 | 288 | /** 289 | * 补休标识 290 | * @param isDeferredDisplay 291 | */ 292 | public void setDeferredDisplay(boolean isDeferredDisplay) { 293 | monthView.setDeferredDisplay(isDeferredDisplay); 294 | } 295 | 296 | 297 | /** 298 | * 是否允许滑动切换日期和年份 299 | * @param isScroll 300 | */ 301 | public void setIsScroll(boolean isScroll){ 302 | monthView.setIsScroll(isScroll); 303 | } 304 | 305 | 306 | public void setIsSelChangeColor(boolean isSelChangeColor,int selChangeTextColor) { 307 | monthView.setIsSelChangeColor(isSelChangeColor,selChangeTextColor); 308 | } 309 | 310 | /** 311 | * 设置单选监听器 312 | * 313 | * @param onDatePickedListener ... 314 | */ 315 | public void setOnDatePickedListener(OnDatePickedListener onDatePickedListener) { 316 | if (monthView.getDPMode() != DPMode.SINGLE) { 317 | throw new RuntimeException( 318 | "Current DPMode does not SINGLE! Please call setMode set DPMode to SINGLE!"); 319 | } 320 | monthView.setOnDatePickedListener(onDatePickedListener); 321 | } 322 | 323 | /** 324 | * 设置多选监听器 325 | * 326 | * @param onDateSelectedListener ... 327 | */ 328 | public void setOnDateSelectedListener(OnDateSelectedListener onDateSelectedListener) { 329 | if (monthView.getDPMode() != DPMode.MULTIPLE) { 330 | throw new RuntimeException( 331 | "Current DPMode does not MULTIPLE! Please call setMode set DPMode to MULTIPLE!"); 332 | } 333 | this.onDateSelectedListener = onDateSelectedListener; 334 | } 335 | 336 | 337 | public void setOnClickSignIn(OnClickSignIn onClickSignIn) { 338 | this.onClickSignIn = onClickSignIn; 339 | } 340 | 341 | 342 | /** 343 | * 左边标题的文字 344 | */ 345 | public void setLeftTitle(String title){ 346 | myMonth.setText(title); 347 | } 348 | 349 | /** 350 | * 中间标题的文字 351 | * @param title 352 | */ 353 | public void setMiddleTitle(String title){ 354 | myTitle.setText(title); 355 | } 356 | 357 | 358 | /** 359 | * 设置右边是否签到 360 | * @param flag ture表示签到 false表示未签到 361 | */ 362 | public void setRightTitle(boolean flag){ 363 | this.isSignIn = flag; 364 | if(isSignIn){ 365 | mySignIn.setText("已签到"); 366 | mySignIn.setTextColor(mContext.getResources().getColor(R.color.font_white_one)); 367 | signIn.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.box_blue_solid)); 368 | }else{ 369 | mySignIn.setText("未签到"); 370 | mySignIn.setTextColor(mContext.getResources().getColor(R.color.gray_normal)); 371 | signIn.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.box_gray_solid)); 372 | } 373 | } 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | } 382 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/DatePicker2.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.util.Log; 6 | import android.util.TypedValue; 7 | import android.view.Gravity; 8 | import android.view.View; 9 | import android.widget.LinearLayout; 10 | import android.widget.RelativeLayout; 11 | import android.widget.TextView; 12 | import android.widget.Toast; 13 | 14 | import com.wsg.mysigndate.R; 15 | 16 | import java.util.List; 17 | 18 | import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 19 | 20 | /** 21 | * 原版DatePicker 22 | */ 23 | public class DatePicker2 extends LinearLayout { 24 | private DPTManager mTManager;// 主题管理器 25 | private DPLManager mLManager;// 语言管理器 26 | 27 | private MonthView monthView;// 月视图 28 | private TextView tvYear, tvMonth;// 年份 月份显示 29 | private TextView tvEnsure;// 确定按钮显示 30 | 31 | 32 | private DatePicker.OnDateSelectedListener onDateSelectedListener;// 日期多选后监听 33 | 34 | public DatePicker2(Context context) { 35 | this(context, null); 36 | } 37 | 38 | public DatePicker2(final Context context, AttributeSet attrs) { 39 | super(context, attrs); 40 | mTManager = DPTManager.getInstance(); 41 | mLManager = DPLManager.getInstance(); 42 | 43 | // 设置排列方向为竖向 44 | setOrientation(VERTICAL); 45 | 46 | LayoutParams llParams = 47 | new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 48 | 49 | // 标题栏根布局 50 | RelativeLayout rlTitle = new RelativeLayout(context); 51 | rlTitle.setBackgroundColor(mTManager.colorTitleBG()); 52 | int rlTitlePadding = MeasureUtil.dp2px(context, 10); 53 | rlTitle.setPadding(rlTitlePadding, rlTitlePadding, rlTitlePadding, rlTitlePadding); 54 | 55 | // 周视图根布局 56 | LinearLayout llWeek = new LinearLayout(context); 57 | llWeek.setBackgroundColor(mTManager.colorTitleBG()); 58 | llWeek.setOrientation(HORIZONTAL); 59 | int llWeekPadding = MeasureUtil.dp2px(context, 5); 60 | llWeek.setPadding(0, llWeekPadding, 0, llWeekPadding); 61 | LayoutParams lpWeek = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 62 | lpWeek.weight = 1; 63 | 64 | // 标题栏子元素布局参数 65 | RelativeLayout.LayoutParams lpYear = 66 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 67 | lpYear.addRule(RelativeLayout.CENTER_VERTICAL); 68 | RelativeLayout.LayoutParams lpMonth = 69 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 70 | lpMonth.addRule(RelativeLayout.CENTER_IN_PARENT); 71 | RelativeLayout.LayoutParams lpEnsure = 72 | new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 73 | lpEnsure.addRule(RelativeLayout.CENTER_VERTICAL); 74 | lpEnsure.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 75 | 76 | // --------------------------------------------------------------------------------标题栏 77 | // 年份显示 78 | tvYear = new TextView(context); 79 | tvYear.setText("2015"); 80 | tvYear.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 81 | tvYear.setTextColor(mTManager.colorTitle()); 82 | 83 | // 月份显示 84 | tvMonth = new TextView(context); 85 | tvMonth.setText("六月"); 86 | tvMonth.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); 87 | tvMonth.setTextColor(mTManager.colorTitle()); 88 | 89 | // 确定显示 90 | tvEnsure = new TextView(context); 91 | tvEnsure.setText(mLManager.titleEnsure()); 92 | tvEnsure.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); 93 | tvEnsure.setTextColor(mTManager.colorTitle()); 94 | tvEnsure.setOnClickListener(new OnClickListener() { 95 | @Override 96 | public void onClick(View v) { 97 | if (null != onDateSelectedListener) { 98 | onDateSelectedListener.onDateSelected(monthView.getDateSelected()); 99 | } 100 | } 101 | }); 102 | 103 | rlTitle.addView(tvYear, lpYear); 104 | rlTitle.addView(tvMonth, lpMonth); 105 | rlTitle.addView(tvEnsure, lpEnsure); 106 | 107 | addView(rlTitle, llParams); 108 | 109 | // --------------------------------------------------------------------------------周视图 110 | for (int i = 0; i < mLManager.titleWeek().length; i++) { 111 | TextView tvWeek = new TextView(context); 112 | tvWeek.setText(mLManager.titleWeek()[i]); 113 | tvWeek.setGravity(Gravity.CENTER); 114 | tvWeek.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); 115 | tvWeek.setTextColor(mTManager.colorTitle()); 116 | llWeek.addView(tvWeek, lpWeek); 117 | } 118 | addView(llWeek, llParams); 119 | 120 | // ------------------------------------------------------------------------------------月视图 121 | monthView = new MonthView(context); 122 | monthView.setOnDateChangeListener(new MonthView.OnDateChangeListener() { 123 | @Override 124 | public void onMonthChange(int month) { 125 | Log.e("月",month+""); 126 | tvMonth.setText(mLManager.titleMonth()[month - 1]); 127 | } 128 | 129 | @Override 130 | public void onYearChange(int year) { 131 | Log.e("年",year+""); 132 | String tmp = String.valueOf(year); 133 | if (tmp.startsWith("-")) { 134 | tmp = tmp.replace("-", mLManager.titleBC()); 135 | } 136 | tvYear.setText(tmp); 137 | } 138 | 139 | @Override 140 | public void onAllChange(int year, int month) { 141 | 142 | } 143 | }); 144 | monthView.setOnDateScrollChangeListener(new MonthView.OnDateScrollChangeListener() { 145 | @Override 146 | public void scrollLeft(int year, int month) { 147 | String str = "向左滑动=="+"年份="+year+"--月份=="+month; 148 | Toast.makeText(context,str,Toast.LENGTH_SHORT).show(); 149 | } 150 | 151 | @Override 152 | public void scrollRight(int year, int month) { 153 | String str = "向右滑动=="+"年份="+year+"--月份=="+month; 154 | Toast.makeText(context,str,Toast.LENGTH_SHORT).show(); 155 | } 156 | 157 | @Override 158 | public void scrollTop(int year, int month) { 159 | String str = "向上滑动=="+"年份="+year+"--月份=="+month; 160 | Toast.makeText(context,str,Toast.LENGTH_SHORT).show(); 161 | } 162 | 163 | @Override 164 | public void scrollBottom(int year, int month) { 165 | String str = "向下滑动=="+"年份="+year+"--月份=="+month; 166 | Toast.makeText(context,str,Toast.LENGTH_SHORT).show(); 167 | } 168 | }); 169 | addView(monthView, llParams); 170 | } 171 | 172 | /** 173 | * 设置初始化年月日期 174 | * 175 | * @param year ... 176 | * @param month ... 177 | */ 178 | public void setDate(int year, int month) { 179 | if (month < 1) { 180 | month = 1; 181 | } 182 | if (month > 12) { 183 | month = 12; 184 | } 185 | monthView.setDate(year, month); 186 | } 187 | 188 | public void setDPDecor(DPDecor decor) { 189 | monthView.setDPDecor(decor); 190 | } 191 | 192 | /** 193 | * 设置日期选择模式 194 | * 195 | * @param mode ... 196 | */ 197 | public void setMode(DPMode mode) { 198 | if (mode != DPMode.MULTIPLE) { 199 | tvEnsure.setVisibility(GONE); 200 | } 201 | monthView.setDPMode(mode); 202 | } 203 | 204 | /** 205 | * 节日标识 206 | * @param isFestivalDisplay 207 | */ 208 | public void setFestivalDisplay(boolean isFestivalDisplay) { 209 | monthView.setFestivalDisplay(isFestivalDisplay); 210 | } 211 | 212 | /** 213 | * 今天标识 214 | * @param isTodayDisplay 215 | */ 216 | public void setTodayDisplay(boolean isTodayDisplay) { 217 | monthView.setTodayDisplay(isTodayDisplay); 218 | } 219 | 220 | /** 221 | * 假期标识 222 | * @param isHolidayDisplay 223 | */ 224 | public void setHolidayDisplay(boolean isHolidayDisplay) { 225 | monthView.setHolidayDisplay(isHolidayDisplay); 226 | } 227 | 228 | /** 229 | * 补休标识 230 | * @param isDeferredDisplay 231 | */ 232 | public void setDeferredDisplay(boolean isDeferredDisplay) { 233 | monthView.setDeferredDisplay(isDeferredDisplay); 234 | } 235 | 236 | /** 237 | * 设置单选监听器 238 | * 239 | * @param onDatePickedListener ... 240 | */ 241 | public void setOnDatePickedListener(DatePicker.OnDatePickedListener onDatePickedListener) { 242 | if (monthView.getDPMode() != DPMode.SINGLE) { 243 | throw new RuntimeException( 244 | "Current DPMode does not SINGLE! Please call setMode set DPMode to SINGLE!"); 245 | } 246 | monthView.setOnDatePickedListener(onDatePickedListener); 247 | } 248 | 249 | /** 250 | * 设置多选监听器 251 | * 252 | * @param onDateSelectedListener ... 253 | */ 254 | public void setOnDateSelectedListener(DatePicker.OnDateSelectedListener onDateSelectedListener) { 255 | if (monthView.getDPMode() != DPMode.MULTIPLE) { 256 | throw new RuntimeException( 257 | "Current DPMode does not MULTIPLE! Please call setMode set DPMode to MULTIPLE!"); 258 | } 259 | this.onDateSelectedListener = onDateSelectedListener; 260 | } 261 | 262 | } 263 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/EN.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | /** 4 | * 英文的默认实现类 5 | * 如果你想实现更多的语言请参考Language{@link DPLManager} 6 | * 7 | * The implementation class of english. 8 | * You can refer to Language{@link DPLManager} if you want to define more language. 9 | * 10 | * @author AigeStudio 2015-03-28 11 | */ 12 | public class EN extends DPLManager { 13 | @Override 14 | public String[] titleMonth() { 15 | return new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; 16 | } 17 | 18 | @Override 19 | public String titleEnsure() { 20 | return "Ok"; 21 | } 22 | 23 | @Override 24 | public String titleBC() { 25 | return "B.C."; 26 | } 27 | 28 | @Override 29 | public String[] titleWeek() { 30 | return new String[]{"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/MeasureUtil.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * 测量工具类 7 | * 8 | * Util of measure. 9 | * 10 | * @author AigeStudio 2015-03-26 11 | */ 12 | public final class MeasureUtil { 13 | public static int dp2px(Context context, float dp) { 14 | float scale = context.getResources().getDisplayMetrics().density; 15 | return (int) (dp * scale + 0.5f); 16 | } 17 | 18 | public static int px2dp(Context context, float px) { 19 | float scale = context.getResources().getDisplayMetrics().density; 20 | return (int) (px / scale + 0.5f); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/MonthView.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.animation.AnimatorSet; 6 | import android.animation.ObjectAnimator; 7 | import android.animation.ValueAnimator; 8 | import android.annotation.TargetApi; 9 | import android.content.Context; 10 | import android.graphics.Canvas; 11 | import android.graphics.Paint; 12 | import android.graphics.Rect; 13 | import android.graphics.Region; 14 | import android.graphics.drawable.ShapeDrawable; 15 | import android.graphics.drawable.shapes.OvalShape; 16 | import android.os.Build; 17 | import android.os.Parcelable; 18 | import android.text.TextUtils; 19 | import android.view.MotionEvent; 20 | import android.view.View; 21 | import android.view.animation.AccelerateInterpolator; 22 | import android.view.animation.DecelerateInterpolator; 23 | import android.widget.Scroller; 24 | 25 | import java.util.ArrayList; 26 | import java.util.Arrays; 27 | import java.util.HashMap; 28 | import java.util.List; 29 | import java.util.Map; 30 | 31 | /** 32 | * MonthView 33 | * 34 | * @author AigeStudio 2015-06-29 35 | */ 36 | public class MonthView extends View { 37 | private final Region[][] MONTH_REGIONS_4 = new Region[4][7]; 38 | private final Region[][] MONTH_REGIONS_5 = new Region[5][7]; 39 | private final Region[][] MONTH_REGIONS_6 = new Region[6][7]; 40 | 41 | private final DPInfo[][] INFO_4 = new DPInfo[4][7]; 42 | private final DPInfo[][] INFO_5 = new DPInfo[5][7]; 43 | private final DPInfo[][] INFO_6 = new DPInfo[6][7]; 44 | 45 | private final Map> REGION_SELECTED = new HashMap<>(); 46 | 47 | private DPCManager mCManager = DPCManager.getInstance(); 48 | private DPTManager mTManager = DPTManager.getInstance(); 49 | 50 | protected Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | 51 | Paint.LINEAR_TEXT_FLAG); 52 | private Scroller mScroller; 53 | private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(); 54 | private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator(); 55 | private OnDateChangeListener onDateChangeListener; 56 | private DatePicker.OnDatePickedListener onDatePickedListener; 57 | private OnDateScrollChangeListener onDateScrollChangeListener; //新加的滑动方向判断 目前没卵用 加着玩 58 | private ScaleAnimationListener scaleAnimationListener; 59 | 60 | private DPMode mDPMode = DPMode.MULTIPLE; 61 | private SlideMode mSlideMode; 62 | private DPDecor mDPDecor; 63 | 64 | private int circleRadius; 65 | private int indexYear, indexMonth; 66 | private int centerYear, centerMonth; 67 | private int leftYear, leftMonth; 68 | private int rightYear, rightMonth; 69 | private int topYear, topMonth; 70 | private int bottomYear, bottomMonth; 71 | private int width, height; 72 | private int sizeDecor, sizeDecor2x, sizeDecor3x; 73 | private int lastPointX, lastPointY; 74 | private int lastMoveX, lastMoveY; 75 | private int criticalWidth, criticalHeight; 76 | private int animZoomOut1, animZoomIn1, animZoomOut2; 77 | 78 | private float sizeTextGregorian, sizeTextFestival; 79 | private float offsetYFestival1, offsetYFestival2; 80 | 81 | private boolean isNewEvent, 82 | isFestivalDisplay = true, 83 | isHolidayDisplay = true, 84 | isTodayDisplay = true, 85 | isDeferredDisplay = true; 86 | 87 | private boolean isScroll = true; //是否允许滑动 88 | 89 | private boolean isSelChangeColor = false; //选中的日期画笔是否变色 90 | private int selChangeTextColor = mTManager.colorG(); 91 | 92 | private Map cirApr = new HashMap<>(); 93 | private Map cirDpr = new HashMap<>(); 94 | 95 | private List dateSelected = new ArrayList<>(); 96 | 97 | public MonthView(Context context) { 98 | super(context); 99 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 100 | scaleAnimationListener = new ScaleAnimationListener(); 101 | } 102 | mScroller = new Scroller(context); 103 | mPaint.setTextAlign(Paint.Align.CENTER); 104 | } 105 | 106 | @Override 107 | protected Parcelable onSaveInstanceState() { 108 | return super.onSaveInstanceState(); 109 | } 110 | 111 | @Override 112 | protected void onRestoreInstanceState(Parcelable state) { 113 | super.onRestoreInstanceState(state); 114 | } 115 | 116 | @Override 117 | public void computeScroll() { 118 | if (mScroller.computeScrollOffset()) { 119 | scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 120 | invalidate(); 121 | } else { 122 | requestLayout(); 123 | } 124 | } 125 | 126 | @Override 127 | public boolean onTouchEvent(MotionEvent event) { 128 | switch (event.getAction()) { 129 | case MotionEvent.ACTION_DOWN: 130 | mScroller.forceFinished(true); 131 | mSlideMode = null; 132 | isNewEvent = true; 133 | lastPointX = (int) event.getX(); 134 | lastPointY = (int) event.getY(); 135 | break; 136 | case MotionEvent.ACTION_MOVE: 137 | if (isNewEvent) { 138 | if (Math.abs(lastPointX - event.getX()) > 100) { 139 | mSlideMode = SlideMode.HOR; 140 | isNewEvent = false; 141 | } else if (Math.abs(lastPointY - event.getY()) > 50) { 142 | mSlideMode = SlideMode.VER; 143 | isNewEvent = false; 144 | } 145 | } 146 | if(isScroll){ 147 | if (mSlideMode == SlideMode.HOR) { 148 | int totalMoveX = (int) (lastPointX - event.getX()) + lastMoveX; 149 | smoothScrollTo(totalMoveX, indexYear * height); 150 | } else if (mSlideMode == SlideMode.VER) { 151 | int totalMoveY = (int) (lastPointY - event.getY()) + lastMoveY; 152 | smoothScrollTo(width * indexMonth, totalMoveY); 153 | } 154 | } 155 | break; 156 | case MotionEvent.ACTION_UP: 157 | if(isScroll){ 158 | if (mSlideMode == SlideMode.VER) { 159 | if (Math.abs(lastPointY - event.getY()) > 25) { 160 | if (lastPointY < event.getY()) { 161 | if (Math.abs(lastPointY - event.getY()) >= criticalHeight) { 162 | indexYear--; 163 | centerYear = centerYear - 1; 164 | 165 | if(null!=onDateScrollChangeListener){ 166 | onDateScrollChangeListener.scrollBottom(centerYear,centerMonth); 167 | } 168 | } 169 | } else if (lastPointY > event.getY()) { 170 | if (Math.abs(lastPointY - event.getY()) >= criticalHeight) { 171 | indexYear++; 172 | centerYear = centerYear + 1; 173 | 174 | if(null!=onDateScrollChangeListener){ 175 | onDateScrollChangeListener.scrollTop(centerYear, centerMonth); 176 | } 177 | } 178 | } 179 | buildRegion(); 180 | computeDate(); 181 | smoothScrollTo(width * indexMonth, height * indexYear); 182 | lastMoveY = height * indexYear; 183 | } else { 184 | defineRegion((int) event.getX(), (int) event.getY()); 185 | } 186 | } else if (mSlideMode == SlideMode.HOR) { 187 | if (Math.abs(lastPointX - event.getX()) > 25) { 188 | if (lastPointX > event.getX() && 189 | Math.abs(lastPointX - event.getX()) >= criticalWidth) { 190 | indexMonth++; 191 | centerMonth = (centerMonth + 1) % 13; 192 | if (centerMonth == 0) { 193 | centerMonth = 1; 194 | centerYear++; 195 | } 196 | if(null!=onDateScrollChangeListener){ 197 | onDateScrollChangeListener.scrollLeft(centerYear, centerMonth); 198 | } 199 | } else if (lastPointX < event.getX() && 200 | Math.abs(lastPointX - event.getX()) >= criticalWidth) { 201 | indexMonth--; 202 | centerMonth = (centerMonth - 1) % 12; 203 | if (centerMonth == 0) { 204 | centerMonth = 12; 205 | centerYear--; 206 | } 207 | if(null!=onDateScrollChangeListener){ 208 | onDateScrollChangeListener.scrollRight(centerYear,centerMonth); 209 | } 210 | } 211 | buildRegion(); 212 | computeDate(); 213 | smoothScrollTo(width * indexMonth, indexYear * height); 214 | lastMoveX = width * indexMonth; 215 | } else { 216 | defineRegion((int) event.getX(), (int) event.getY()); 217 | } 218 | } else { 219 | defineRegion((int) event.getX(), (int) event.getY()); 220 | } 221 | } 222 | break; 223 | } 224 | return true; 225 | } 226 | 227 | @Override 228 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 229 | int measureWidth = MeasureSpec.getSize(widthMeasureSpec); 230 | setMeasuredDimension(measureWidth, (int) (measureWidth * 6F / 7F)); 231 | } 232 | 233 | @Override 234 | protected void onSizeChanged(int w, int h, int oldW, int oldH) { 235 | width = w; 236 | height = h; 237 | 238 | criticalWidth = (int) (1F / 5F * width); 239 | criticalHeight = (int) (1F / 5F * height); 240 | 241 | int cellW = (int) (w / 7F); 242 | int cellH4 = (int) (h / 4F); 243 | int cellH5 = (int) (h / 5F); 244 | int cellH6 = (int) (h / 6F); 245 | 246 | circleRadius = cellW; 247 | 248 | animZoomOut1 = (int) (cellW * 1.2F); 249 | animZoomIn1 = (int) (cellW * 0.8F); 250 | animZoomOut2 = (int) (cellW * 1.1F); 251 | 252 | sizeDecor = (int) (cellW / 3F); 253 | sizeDecor2x = sizeDecor * 2; 254 | sizeDecor3x = sizeDecor * 3; 255 | 256 | sizeTextGregorian = width / 20F; 257 | mPaint.setTextSize(sizeTextGregorian); 258 | 259 | float heightGregorian = mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top; 260 | sizeTextFestival = width / 40F; 261 | mPaint.setTextSize(sizeTextFestival); 262 | 263 | float heightFestival = mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top; 264 | offsetYFestival1 = (((Math.abs(mPaint.ascent() + mPaint.descent())) / 2F) + 265 | heightFestival / 2F + heightGregorian / 2F) / 2F; 266 | offsetYFestival2 = offsetYFestival1 * 2F; 267 | 268 | for (int i = 0; i < MONTH_REGIONS_4.length; i++) { 269 | for (int j = 0; j < MONTH_REGIONS_4[i].length; j++) { 270 | Region region = new Region(); 271 | region.set((j * cellW), (i * cellH4), cellW + (j * cellW), 272 | cellW + (i * cellH4)); 273 | MONTH_REGIONS_4[i][j] = region; 274 | } 275 | } 276 | for (int i = 0; i < MONTH_REGIONS_5.length; i++) { 277 | for (int j = 0; j < MONTH_REGIONS_5[i].length; j++) { 278 | Region region = new Region(); 279 | region.set((j * cellW), (i * cellH5), cellW + (j * cellW), 280 | cellW + (i * cellH5)); 281 | MONTH_REGIONS_5[i][j] = region; 282 | } 283 | } 284 | for (int i = 0; i < MONTH_REGIONS_6.length; i++) { 285 | for (int j = 0; j < MONTH_REGIONS_6[i].length; j++) { 286 | Region region = new Region(); 287 | region.set((j * cellW), (i * cellH6), cellW + (j * cellW), 288 | cellW + (i * cellH6)); 289 | MONTH_REGIONS_6[i][j] = region; 290 | } 291 | } 292 | } 293 | 294 | @Override 295 | protected void onDraw(Canvas canvas) { 296 | canvas.drawColor(mTManager.colorBG()); 297 | 298 | draw(canvas, width * indexMonth, (indexYear - 1) * height, topYear, topMonth); 299 | draw(canvas, width * (indexMonth - 1), height * indexYear, leftYear, leftMonth); 300 | draw(canvas, width * indexMonth, indexYear * height, centerYear, centerMonth); 301 | draw(canvas, width * (indexMonth + 1), height * indexYear, rightYear, rightMonth); 302 | draw(canvas, width * indexMonth, (indexYear + 1) * height, bottomYear, bottomMonth); 303 | 304 | drawBGCircle(canvas); 305 | } 306 | 307 | private void drawBGCircle(Canvas canvas) { 308 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 309 | for (String s : cirDpr.keySet()) { 310 | BGCircle circle = cirDpr.get(s); 311 | drawBGCircle(canvas, circle); 312 | } 313 | } 314 | for (String s : cirApr.keySet()) { 315 | BGCircle circle = cirApr.get(s); 316 | drawBGCircle(canvas, circle); 317 | } 318 | } 319 | 320 | private void drawBGCircle(Canvas canvas, BGCircle circle) { 321 | canvas.save(); 322 | canvas.translate(circle.getX() - circle.getRadius() / 2, 323 | circle.getY() - circle.getRadius() / 2); 324 | circle.getShape().getShape().resize(circle.getRadius(), circle.getRadius()); 325 | circle.getShape().draw(canvas); 326 | canvas.restore(); 327 | } 328 | 329 | private void draw(Canvas canvas, int x, int y, int year, int month) { 330 | canvas.save(); 331 | canvas.translate(x, y); 332 | DPInfo[][] info = mCManager.obtainDPInfo(year, month); 333 | DPInfo[][] result; 334 | Region[][] tmp; 335 | if (TextUtils.isEmpty(info[4][0].strG)) { 336 | tmp = MONTH_REGIONS_4; 337 | arrayClear(INFO_4); 338 | result = arrayCopy(info, INFO_4); 339 | } else if (TextUtils.isEmpty(info[5][0].strG)) { 340 | tmp = MONTH_REGIONS_5; 341 | arrayClear(INFO_5); 342 | result = arrayCopy(info, INFO_5); 343 | } else { 344 | tmp = MONTH_REGIONS_6; 345 | arrayClear(INFO_6); 346 | result = arrayCopy(info, INFO_6); 347 | } 348 | for (int i = 0; i < result.length; i++) { 349 | for (int j = 0; j < result[i].length; j++) { 350 | draw(canvas, tmp[i][j].getBounds(), info[i][j]); 351 | } 352 | } 353 | canvas.restore(); 354 | } 355 | 356 | private void draw(Canvas canvas, Rect rect, DPInfo info) { 357 | drawBG(canvas, rect, info); 358 | drawGregorian(canvas, rect, info.strG, info.isWeekend); 359 | if (isFestivalDisplay) drawFestival(canvas, rect, info.strF, info.isFestival); 360 | drawDecor(canvas, rect, info); 361 | } 362 | 363 | private void drawBG(Canvas canvas, Rect rect, DPInfo info) { 364 | if (null != mDPDecor && info.isDecorBG) { 365 | // LogUtils.e("drawBG===="+info.strG); 366 | mDPDecor.drawDecorBG(canvas, rect, mPaint, 367 | centerYear + "-" + centerMonth + "-" + info.strG); 368 | } 369 | if (info.isToday && isTodayDisplay) { 370 | drawBGToday(canvas, rect); 371 | } else { 372 | if (isHolidayDisplay) drawBGHoliday(canvas, rect, info.isHoliday); 373 | if (isDeferredDisplay) drawBGDeferred(canvas, rect, info.isDeferred); 374 | } 375 | } 376 | 377 | private void drawBGToday(Canvas canvas, Rect rect) { 378 | mPaint.setColor(mTManager.colorToday()); 379 | canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint); 380 | } 381 | 382 | private void drawBGHoliday(Canvas canvas, Rect rect, boolean isHoliday) { 383 | mPaint.setColor(mTManager.colorHoliday()); 384 | if (isHoliday) canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint); 385 | } 386 | 387 | private void drawBGDeferred(Canvas canvas, Rect rect, boolean isDeferred) { 388 | mPaint.setColor(mTManager.colorDeferred()); 389 | if (isDeferred) 390 | canvas.drawCircle(rect.centerX(), rect.centerY(), circleRadius / 2F, mPaint); 391 | } 392 | 393 | private void drawGregorian(Canvas canvas, Rect rect, String str, boolean isWeekend) { 394 | 395 | // LogUtils.e("drawGregorian====" + str); 396 | // LogUtils.e("getSelDatLIst====" + mCManager.getSelDateList().toString()); 397 | 398 | 399 | mPaint.setTextSize(sizeTextGregorian); 400 | // if (isWeekend) { 401 | // mPaint.setColor(mTManager.colorWeekend()); 402 | // } else { 403 | // mPaint.setColor(mTManager.colorG()); 404 | // } 405 | // if(isSelChangeColor&&mCManager.getSelDateList().contains(str)){ //选中了变色 406 | // mPaint.setColor(selChangeTextColor); 407 | // } 408 | 409 | 410 | if(isSelChangeColor&&mCManager.getSelDateList().contains(str)){ //选中了变色 411 | mPaint.setColor(selChangeTextColor); 412 | } else if (isWeekend) { 413 | mPaint.setColor(mTManager.colorWeekend()); 414 | } 415 | else { 416 | mPaint.setColor(mTManager.colorG()); 417 | } 418 | 419 | 420 | float y = rect.centerY(); 421 | if (!isFestivalDisplay) 422 | y = rect.centerY() + Math.abs(mPaint.ascent()) - (mPaint.descent() - mPaint.ascent()) / 2F; 423 | canvas.drawText(str, rect.centerX(), y, mPaint); 424 | } 425 | 426 | private void drawFestival(Canvas canvas, Rect rect, String str, boolean isFestival) { 427 | mPaint.setTextSize(sizeTextFestival); 428 | if (isFestival) { 429 | mPaint.setColor(mTManager.colorF()); 430 | } else { 431 | mPaint.setColor(mTManager.colorL()); 432 | } 433 | if (str.contains("&")) { 434 | String[] s = str.split("&"); 435 | String str1 = s[0]; 436 | if (mPaint.measureText(str1) > rect.width()) { 437 | float ch = mPaint.measureText(str1, 0, 1); 438 | int length = (int) (rect.width() / ch); 439 | canvas.drawText(str1.substring(0, length), rect.centerX(), 440 | rect.centerY() + offsetYFestival1, mPaint); 441 | canvas.drawText(str1.substring(length), rect.centerX(), 442 | rect.centerY() + offsetYFestival2, mPaint); 443 | } else { 444 | canvas.drawText(str1, rect.centerX(), 445 | rect.centerY() + offsetYFestival1, mPaint); 446 | String str2 = s[1]; 447 | if (mPaint.measureText(str2) < rect.width()) { 448 | canvas.drawText(str2, rect.centerX(), 449 | rect.centerY() + offsetYFestival2, mPaint); 450 | } 451 | } 452 | } else { 453 | if (mPaint.measureText(str) > rect.width()) { 454 | float ch = 0.0F; 455 | for (char c : str.toCharArray()) { 456 | float tmp = mPaint.measureText(String.valueOf(c)); 457 | if (tmp > ch) { 458 | ch = tmp; 459 | } 460 | } 461 | int length = (int) (rect.width() / ch); 462 | canvas.drawText(str.substring(0, length), rect.centerX(), 463 | rect.centerY() + offsetYFestival1, mPaint); 464 | canvas.drawText(str.substring(length), rect.centerX(), 465 | rect.centerY() + offsetYFestival2, mPaint); 466 | } else { 467 | canvas.drawText(str, rect.centerX(), 468 | rect.centerY() + offsetYFestival1, mPaint); 469 | } 470 | } 471 | } 472 | 473 | private void drawDecor(Canvas canvas, Rect rect, DPInfo info) { 474 | if (!TextUtils.isEmpty(info.strG)) { 475 | String data = centerYear + "-" + centerMonth + "-" + info.strG; 476 | if (null != mDPDecor && info.isDecorTL) { 477 | canvas.save(); 478 | canvas.clipRect(rect.left, rect.top, rect.left + sizeDecor, rect.top + sizeDecor); 479 | mDPDecor.drawDecorTL(canvas, canvas.getClipBounds(), mPaint, data); 480 | canvas.restore(); 481 | } 482 | if (null != mDPDecor && info.isDecorT) { 483 | canvas.save(); 484 | canvas.clipRect(rect.left + sizeDecor, rect.top, rect.left + sizeDecor2x, 485 | rect.top + sizeDecor); 486 | mDPDecor.drawDecorT(canvas, canvas.getClipBounds(), mPaint, data); 487 | canvas.restore(); 488 | } 489 | if (null != mDPDecor && info.isDecorTR) { 490 | canvas.save(); 491 | canvas.clipRect(rect.left + sizeDecor2x, rect.top, rect.left + sizeDecor3x, 492 | rect.top + sizeDecor); 493 | mDPDecor.drawDecorTR(canvas, canvas.getClipBounds(), mPaint, data); 494 | canvas.restore(); 495 | } 496 | if (null != mDPDecor && info.isDecorL) { 497 | canvas.save(); 498 | canvas.clipRect(rect.left, rect.top + sizeDecor, rect.left + sizeDecor, 499 | rect.top + sizeDecor2x); 500 | mDPDecor.drawDecorL(canvas, canvas.getClipBounds(), mPaint, data); 501 | canvas.restore(); 502 | } 503 | if (null != mDPDecor && info.isDecorR) { 504 | canvas.save(); 505 | canvas.clipRect(rect.left + sizeDecor2x, rect.top + sizeDecor, 506 | rect.left + sizeDecor3x, rect.top + sizeDecor2x); 507 | mDPDecor.drawDecorR(canvas, canvas.getClipBounds(), mPaint, data); 508 | canvas.restore(); 509 | } 510 | } 511 | } 512 | 513 | List getDateSelected() { 514 | return dateSelected; 515 | } 516 | 517 | void setOnDateChangeListener(OnDateChangeListener onDateChangeListener) { 518 | this.onDateChangeListener = onDateChangeListener; 519 | } 520 | 521 | public void setOnDatePickedListener(DatePicker.OnDatePickedListener onDatePickedListener) { 522 | this.onDatePickedListener = onDatePickedListener; 523 | } 524 | 525 | public void setOnDateScrollChangeListener(OnDateScrollChangeListener onDateScrollChangeListener) { 526 | this.onDateScrollChangeListener = onDateScrollChangeListener; 527 | } 528 | 529 | void setDPMode(DPMode mode) { 530 | this.mDPMode = mode; 531 | } 532 | 533 | void setDPDecor(DPDecor decor) { 534 | this.mDPDecor = decor; 535 | } 536 | 537 | DPMode getDPMode() { 538 | return mDPMode; 539 | } 540 | 541 | void setDate(int year, int month) { 542 | centerYear = year; 543 | centerMonth = month; 544 | indexYear = 0; 545 | indexMonth = 0; 546 | buildRegion(); 547 | computeDate(); 548 | requestLayout(); 549 | invalidate(); 550 | } 551 | 552 | void setFestivalDisplay(boolean isFestivalDisplay) { 553 | this.isFestivalDisplay = isFestivalDisplay; 554 | } 555 | 556 | void setTodayDisplay(boolean isTodayDisplay) { 557 | this.isTodayDisplay = isTodayDisplay; 558 | } 559 | 560 | void setHolidayDisplay(boolean isHolidayDisplay) { 561 | this.isHolidayDisplay = isHolidayDisplay; 562 | } 563 | 564 | void setDeferredDisplay(boolean isDeferredDisplay) { 565 | this.isDeferredDisplay = isDeferredDisplay; 566 | } 567 | 568 | void setIsScroll(boolean isScroll){ 569 | this.isScroll = isScroll; 570 | } 571 | 572 | public void setIsSelChangeColor(boolean isSelChangeColor,int selChangeTextColor) { 573 | this.isSelChangeColor = isSelChangeColor; 574 | this.selChangeTextColor = selChangeTextColor; 575 | } 576 | 577 | private void smoothScrollTo(int fx, int fy) { 578 | int dx = fx - mScroller.getFinalX(); 579 | int dy = fy - mScroller.getFinalY(); 580 | smoothScrollBy(dx, dy); 581 | } 582 | 583 | private void smoothScrollBy(int dx, int dy) { 584 | mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, 500); 585 | invalidate(); 586 | } 587 | 588 | private BGCircle createCircle(float x, float y) { 589 | OvalShape circle = new OvalShape(); 590 | circle.resize(0, 0); 591 | ShapeDrawable drawable = new ShapeDrawable(circle); 592 | BGCircle circle1 = new BGCircle(drawable); 593 | circle1.setX(x); 594 | circle1.setY(y); 595 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 596 | circle1.setRadius(circleRadius); 597 | } 598 | drawable.getPaint().setColor(mTManager.colorBGCircle()); 599 | return circle1; 600 | } 601 | 602 | private void buildRegion() { 603 | String key = indexYear + ":" + indexMonth; 604 | if (!REGION_SELECTED.containsKey(key)) { 605 | REGION_SELECTED.put(key, new ArrayList()); 606 | } 607 | } 608 | 609 | private void arrayClear(DPInfo[][] info) { 610 | for (DPInfo[] anInfo : info) { 611 | Arrays.fill(anInfo, null); 612 | } 613 | } 614 | 615 | private DPInfo[][] arrayCopy(DPInfo[][] src, DPInfo[][] dst) { 616 | for (int i = 0; i < dst.length; i++) { 617 | System.arraycopy(src[i], 0, dst[i], 0, dst[i].length); 618 | } 619 | return dst; 620 | } 621 | 622 | private void defineRegion(int x, int y) { 623 | DPInfo[][] info = mCManager.obtainDPInfo(centerYear, centerMonth); 624 | Region[][] tmp; 625 | if (TextUtils.isEmpty(info[4][0].strG)) { 626 | tmp = MONTH_REGIONS_4; 627 | } else if (TextUtils.isEmpty(info[5][0].strG)) { 628 | tmp = MONTH_REGIONS_5; 629 | } else { 630 | tmp = MONTH_REGIONS_6; 631 | } 632 | for (int i = 0; i < tmp.length; i++) { 633 | for (int j = 0; j < tmp[i].length; j++) { 634 | Region region = tmp[i][j]; 635 | if (TextUtils.isEmpty(mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG)) { 636 | continue; 637 | } 638 | if (region.contains(x, y)) { 639 | List regions = REGION_SELECTED.get(indexYear + ":" + indexMonth); 640 | if (mDPMode == DPMode.SINGLE) { 641 | cirApr.clear(); 642 | regions.add(region); 643 | final String date = centerYear + "-" + centerMonth + "-" + 644 | mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG; 645 | BGCircle circle = createCircle( 646 | region.getBounds().centerX() + indexMonth * width, 647 | region.getBounds().centerY() + indexYear * height); 648 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 649 | ValueAnimator animScale1 = 650 | ObjectAnimator.ofInt(circle, "radius", 0, animZoomOut1); 651 | animScale1.setDuration(250); 652 | animScale1.setInterpolator(decelerateInterpolator); 653 | animScale1.addUpdateListener(scaleAnimationListener); 654 | 655 | ValueAnimator animScale2 = 656 | ObjectAnimator.ofInt(circle, "radius", animZoomOut1, animZoomIn1); 657 | animScale2.setDuration(100); 658 | animScale2.setInterpolator(accelerateInterpolator); 659 | animScale2.addUpdateListener(scaleAnimationListener); 660 | 661 | ValueAnimator animScale3 = 662 | ObjectAnimator.ofInt(circle, "radius", animZoomIn1, animZoomOut2); 663 | animScale3.setDuration(150); 664 | animScale3.setInterpolator(decelerateInterpolator); 665 | animScale3.addUpdateListener(scaleAnimationListener); 666 | 667 | ValueAnimator animScale4 = 668 | ObjectAnimator.ofInt(circle, "radius", animZoomOut2, circleRadius); 669 | animScale4.setDuration(50); 670 | animScale4.setInterpolator(accelerateInterpolator); 671 | animScale4.addUpdateListener(scaleAnimationListener); 672 | 673 | AnimatorSet animSet = new AnimatorSet(); 674 | animSet.playSequentially(animScale1, animScale2, animScale3, animScale4); 675 | animSet.addListener(new AnimatorListenerAdapter() { 676 | @Override 677 | public void onAnimationEnd(Animator animation) { 678 | if (null != onDatePickedListener) { 679 | onDatePickedListener.onDatePicked(date); 680 | } 681 | } 682 | }); 683 | animSet.start(); 684 | } 685 | cirApr.put(date, circle); 686 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 687 | invalidate(); 688 | if (null != onDatePickedListener) { 689 | onDatePickedListener.onDatePicked(date); 690 | } 691 | } 692 | } else if (mDPMode == DPMode.MULTIPLE) { 693 | if (regions.contains(region)) { 694 | regions.remove(region); 695 | } else { 696 | regions.add(region); 697 | } 698 | final String date = centerYear + "-" + centerMonth + "-" + 699 | mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG; 700 | if (dateSelected.contains(date)) { 701 | dateSelected.remove(date); 702 | BGCircle circle = cirApr.get(date); 703 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 704 | ValueAnimator animScale = ObjectAnimator.ofInt(circle, "radius", circleRadius, 0); 705 | animScale.setDuration(250); 706 | animScale.setInterpolator(accelerateInterpolator); 707 | animScale.addUpdateListener(scaleAnimationListener); 708 | animScale.addListener(new AnimatorListenerAdapter() { 709 | @Override 710 | public void onAnimationEnd(Animator animation) { 711 | cirDpr.remove(date); 712 | } 713 | }); 714 | animScale.start(); 715 | cirDpr.put(date, circle); 716 | } 717 | cirApr.remove(date); 718 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 719 | invalidate(); 720 | } 721 | } else { 722 | dateSelected.add(date); 723 | BGCircle circle = createCircle( 724 | region.getBounds().centerX() + indexMonth * width, 725 | region.getBounds().centerY() + indexYear * height); 726 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 727 | ValueAnimator animScale1 = 728 | ObjectAnimator.ofInt(circle, "radius", 0, animZoomOut1); 729 | animScale1.setDuration(250); 730 | animScale1.setInterpolator(decelerateInterpolator); 731 | animScale1.addUpdateListener(scaleAnimationListener); 732 | 733 | ValueAnimator animScale2 = 734 | ObjectAnimator.ofInt(circle, "radius", animZoomOut1, animZoomIn1); 735 | animScale2.setDuration(100); 736 | animScale2.setInterpolator(accelerateInterpolator); 737 | animScale2.addUpdateListener(scaleAnimationListener); 738 | 739 | ValueAnimator animScale3 = 740 | ObjectAnimator.ofInt(circle, "radius", animZoomIn1, animZoomOut2); 741 | animScale3.setDuration(150); 742 | animScale3.setInterpolator(decelerateInterpolator); 743 | animScale3.addUpdateListener(scaleAnimationListener); 744 | 745 | ValueAnimator animScale4 = 746 | ObjectAnimator.ofInt(circle, "radius", animZoomOut2, circleRadius); 747 | animScale4.setDuration(50); 748 | animScale4.setInterpolator(accelerateInterpolator); 749 | animScale4.addUpdateListener(scaleAnimationListener); 750 | 751 | AnimatorSet animSet = new AnimatorSet(); 752 | animSet.playSequentially(animScale1, animScale2, animScale3, animScale4); 753 | animSet.start(); 754 | } 755 | cirApr.put(date, circle); 756 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 757 | invalidate(); 758 | } 759 | } 760 | } else if (mDPMode == DPMode.NONE) { 761 | if (regions.contains(region)) { 762 | regions.remove(region); 763 | } else { 764 | regions.add(region); 765 | } 766 | final String date = centerYear + "-" + centerMonth + "-" + 767 | mCManager.obtainDPInfo(centerYear, centerMonth)[i][j].strG; 768 | if (dateSelected.contains(date)) { 769 | dateSelected.remove(date); 770 | } else { 771 | dateSelected.add(date); 772 | } 773 | } 774 | } 775 | } 776 | } 777 | } 778 | 779 | private void computeDate() { 780 | rightYear = leftYear = centerYear; 781 | topYear = centerYear - 1; 782 | bottomYear = centerYear + 1; 783 | 784 | topMonth = centerMonth; 785 | bottomMonth = centerMonth; 786 | 787 | rightMonth = centerMonth + 1; 788 | leftMonth = centerMonth - 1; 789 | 790 | if (centerMonth == 12) { 791 | rightYear++; 792 | rightMonth = 1; 793 | } 794 | if (centerMonth == 1) { 795 | leftYear--; 796 | leftMonth = 12; 797 | } 798 | if (null != onDateChangeListener) { 799 | onDateChangeListener.onYearChange(centerYear); 800 | onDateChangeListener.onMonthChange(centerMonth); 801 | onDateChangeListener.onAllChange(centerYear,centerMonth); 802 | } 803 | } 804 | 805 | interface OnDateChangeListener { 806 | void onMonthChange(int month); 807 | 808 | void onYearChange(int year); 809 | 810 | void onAllChange(int year, int month); 811 | } 812 | 813 | interface OnDateScrollChangeListener{ 814 | void scrollLeft(int year, int month); //往左边滑动 月份加一 815 | void scrollRight(int year, int month); //往右边滑动 月份减一 816 | void scrollTop(int year, int month); //往上边滑动 年份加一 817 | void scrollBottom(int year, int month); //往下边滑动 年份加一 818 | 819 | } 820 | 821 | private enum SlideMode { 822 | VER, 823 | HOR 824 | } 825 | 826 | private class BGCircle { 827 | private float x, y; 828 | private int radius; 829 | 830 | private ShapeDrawable shape; 831 | 832 | public BGCircle(ShapeDrawable shape) { 833 | this.shape = shape; 834 | } 835 | 836 | public float getX() { 837 | return x; 838 | } 839 | 840 | public void setX(float x) { 841 | this.x = x; 842 | } 843 | 844 | public float getY() { 845 | return y; 846 | } 847 | 848 | public void setY(float y) { 849 | this.y = y; 850 | } 851 | 852 | public int getRadius() { 853 | return radius; 854 | } 855 | 856 | public void setRadius(int radius) { 857 | this.radius = radius; 858 | } 859 | 860 | public ShapeDrawable getShape() { 861 | return shape; 862 | } 863 | 864 | public void setShape(ShapeDrawable shape) { 865 | this.shape = shape; 866 | } 867 | } 868 | 869 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 870 | private class ScaleAnimationListener implements ValueAnimator.AnimatorUpdateListener { 871 | @Override 872 | public void onAnimationUpdate(ValueAnimator animation) { 873 | MonthView.this.invalidate(); 874 | } 875 | } 876 | 877 | 878 | } 879 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysign/mydatepicker/SolarTerm.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysign.mydatepicker; 2 | 3 | 4 | /** 5 | * 农历二十四节气算法 6 | * 该算法目前仅对外提供一个接口方法获取某年的节气数据{@link #buildSolarTerm(int)} 7 | * 8 | * Algorithm of lunar solar term. 9 | * This algorithm provide a public method to get the all solar term of year.{@link #buildSolarTerm(int)} 10 | * 11 | * @author AigeStudio 2015-06-16 12 | */ 13 | final class SolarTerm { 14 | private static final double E10[] = {1.75347045673, 0.00000000000, 0.0000000000, 0.03341656456, 4.66925680417, 6283.0758499914, 0.00034894275, 4.62610241759, 12566.1516999828, 0.00003417571, 2.82886579606, 3.5231183490, 0.00003497056, 2.74411800971, 5753.3848848968, 0.00003135896, 3.62767041758, 77713.7714681205, 0.00002676218, 4.41808351397, 7860.4193924392, 0.00002342687, 6.13516237631, 3930.2096962196, 0.00001273166, 2.03709655772, 529.6909650946, 0.00001324292, 0.74246356352, 11506.7697697936, 0.00000901855, 2.04505443513, 26.2983197998, 0.00001199167, 1.10962944315, 1577.3435424478, 0.00000857223, 3.50849156957, 398.1490034082, 0.00000779786, 1.17882652114, 5223.6939198022, 0.00000990250, 5.23268129594, 5884.9268465832, 0.00000753141, 2.53339053818, 5507.5532386674, 0.00000505264, 4.58292563052, 18849.2275499742, 0.00000492379, 4.20506639861, 775.5226113240, 0.00000356655, 2.91954116867, 0.0673103028, 0.00000284125, 1.89869034186, 796.2980068164, 0.00000242810, 0.34481140906, 5486.7778431750, 0.00000317087, 5.84901952218, 11790.6290886588, 0.00000271039, 0.31488607649, 10977.0788046990, 0.00000206160, 4.80646606059, 2544.3144198834, 0.00000205385, 1.86947813692, 5573.1428014331, 0.00000202261, 2.45767795458, 6069.7767545534, 0.00000126184, 1.08302630210, 20.7753954924, 0.00000155516, 0.83306073807, 213.2990954380, 0.00000115132, 0.64544911683, 0.9803210682, 0.00000102851, 0.63599846727, 4694.0029547076, 0.00000101724, 4.26679821365, 7.1135470008, 0.00000099206, 6.20992940258, 2146.1654164752, 0.00000132212, 3.41118275555, 2942.4634232916, 0.00000097607, 0.68101272270, 155.4203994342, 0.00000085128, 1.29870743025, 6275.9623029906, 0.00000074651, 1.75508916159, 5088.6288397668, 0.00000101895, 0.97569221824, 15720.8387848784, 0.00000084711, 3.67080093025, 71430.6956181291, 0.00000073547, 4.67926565481, 801.8209311238, 0.00000073874, 3.50319443167, 3154.6870848956, 0.00000078756, 3.03698313141, 12036.4607348882, 0.00000079637, 1.80791330700, 17260.1546546904, 0.00000085803, 5.98322631256, 161000.6857376741, 0.00000056963, 2.78430398043, 6286.5989683404, 0.00000061148, 1.81839811024, 7084.8967811152, 0.00000069627, 0.83297596966, 9437.7629348870, 0.00000056116, 4.38694880779, 14143.4952424306, 0.00000062449, 3.97763880587, 8827.3902698748, 0.00000051145, 0.28306864501, 5856.4776591154, 0.00000055577, 3.47006009062, 6279.5527316424, 0.00000041036, 5.36817351402, 8429.2412664666, 0.00000051605, 1.33282746983, 1748.0164130670, 0.00000051992, 0.18914945834, 12139.5535091068, 0.00000049000, 0.48735065033, 1194.4470102246, 0.00000039200, 6.16832995016, 10447.3878396044, 0.00000035566, 1.77597314691, 6812.7668150860, 0.00000036770, 6.04133859347, 10213.2855462110, 0.00000036596, 2.56955238628, 1059.3819301892, 0.00000033291, 0.59309499459, 17789.8456197850, 0.00000035954, 1.70876111898, 2352.8661537718}; 15 | 16 | private static final double E11[] = {6283.31966747491, 0.00000000000, 0.0000000000, 0.00206058863, 2.67823455584, 6283.0758499914, 0.00004303430, 2.63512650414, 12566.1516999828, 0.00000425264, 1.59046980729, 3.5231183490, 0.00000108977, 2.96618001993, 1577.3435424478, 0.00000093478, 2.59212835365, 18849.2275499742, 0.00000119261, 5.79557487799, 26.2983197998, 0.00000072122, 1.13846158196, 529.6909650946, 0.00000067768, 1.87472304791, 398.1490034082, 0.00000067327, 4.40918235168, 5507.5532386674, 0.00000059027, 2.88797038460, 5223.6939198022, 0.00000055976, 2.17471680261, 155.4203994342, 0.00000045407, 0.39803079805, 796.2980068164, 0.00000036369, 0.46624739835, 775.5226113240, 0.00000028958, 2.64707383882, 7.1135470008, 0.00000019097, 1.84628332577, 5486.7778431750, 0.00000020844, 5.34138275149, 0.9803210682, 0.00000018508, 4.96855124577, 213.2990954380, 0.00000016233, 0.03216483047, 2544.3144198834, 0.00000017293, 2.99116864949, 6275.9623029906}; 17 | 18 | private static final double E12[] = {0.00052918870, 0.00000000000, 0.0000000000, 0.00008719837, 1.07209665242, 6283.0758499914, 0.00000309125, 0.86728818832, 12566.1516999828, 0.00000027339, 0.05297871691, 3.5231183490, 0.00000016334, 5.18826691036, 26.2983197998, 0.00000015752, 3.68457889430, 155.4203994342, 0.00000009541, 0.75742297675, 18849.2275499742, 0.00000008937, 2.05705419118, 77713.7714681205, 0.00000006952, 0.82673305410, 775.5226113240, 0.00000005064, 4.66284525271, 1577.3435424478}; 19 | 20 | private static final double E13[] = {0.00000289226, 5.84384198723, 6283.0758499914, 0.00000034955, 0.00000000000, 0.0000000000, 0.00000016819, 5.48766912348, 12566.1516999828}; 21 | 22 | private static final double E14[] = {0.00000114084, 3.14159265359, 0.0000000000, 0.00000007717, 4.13446589358, 6283.0758499914, 0.00000000765, 3.83803776214, 12566.1516999828}; 23 | 24 | private static final double E15[] = {0.00000000878, 3.14159265359, 0.0000000000}; 25 | 26 | private static final double E20[] = {0.00000279620, 3.19870156017, 84334.6615813083, 0.00000101643, 5.42248619256, 5507.5532386674, 0.00000080445, 3.88013204458, 5223.6939198022, 0.00000043806, 3.70444689758, 2352.8661537718, 0.00000031933, 4.00026369781, 1577.3435424478, 0.00000022724, 3.98473831560, 1047.7473117547, 0.00000016392, 3.56456119782, 5856.4776591154, 0.00000018141, 4.98367470263, 6283.0758499914, 0.00000014443, 3.70275614914, 9437.7629348870, 0.00000014304, 3.41117857525, 10213.2855462110}; 27 | 28 | private static final double E21[] = {0.00000009030, 3.89729061890, 5507.5532386674, 0.00000006177, 1.73038850355, 5223.6939198022}; 29 | 30 | private static final double E30[] = {1.00013988799, 0.00000000000, 0.0000000000, 0.01670699626, 3.09846350771, 6283.0758499914, 0.00013956023, 3.05524609620, 12566.1516999828, 0.00003083720, 5.19846674381, 77713.7714681205, 0.00001628461, 1.17387749012, 5753.3848848968, 0.00001575568, 2.84685245825, 7860.4193924392, 0.00000924799, 5.45292234084, 11506.7697697936, 0.00000542444, 4.56409149777, 3930.2096962196}; 31 | 32 | private static final double E31[] = {0.00103018608, 1.10748969588, 6283.0758499914, 0.00001721238, 1.06442301418, 12566.1516999828, 0.00000702215, 3.14159265359, 0.0000000000}; 33 | 34 | private static final double E32[] = {0.00004359385, 5.78455133738, 6283.0758499914}; 35 | 36 | private static final double E33[] = {0.00000144595, 4.27319435148, 6283.0758499914}; 37 | 38 | private static final double M10[] = {22639.5858800, 2.3555545723, 8328.6914247251, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 4586.4383203, 8.0413790709, 7214.0628654588, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10, 2369.9139357, 10.3969336431, 15542.7542901840, -6.6188121E-05, 6.3946925E-08, -3.0872935E-10, 769.0257187, 4.7111091445, 16657.3828494503, 3.0462550E-04, 5.0082223E-07, -2.3726782E-09, -666.4175399, -0.0431256817, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, -411.5957339, 3.2558104895, 16866.9323152810, -1.2804259E-04, -9.8998954E-09, 4.0433461E-11, 211.6555524, 5.6858244986, -1114.6285592663, -3.7081362E-04, -4.3687530E-07, 2.0639488E-09, 205.4359530, 8.0845047526, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 191.9561973, 12.7524882154, 23871.4457149091, 8.6124629E-05, 3.1435804E-07, -1.4950684E-09, 164.7286185, 10.4400593249, 14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, -147.3213842, -2.3986802540, -7700.3894694766, -1.5497663E-04, -2.4979472E-07, 1.1318993E-09, -124.9881185, 5.1984668216, 7771.3771450920, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, -109.3803637, 2.3124288905, 8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 55.1770578, 7.1411231536, -1324.1780250970, 6.1854469E-05, 7.3846820E-08, -3.4916281E-10, -45.0996092, 5.6113650618, 25195.6237400061, 2.4270161E-05, 2.4051122E-07, -1.1459056E-09, 39.5333010, -0.9002559173, -8538.2408905558, 2.8035534E-04, 2.6031101E-07, -1.2267725E-09, 38.4298346, 18.4383127140, 22756.8171556428, -2.8468899E-04, -1.2251727E-07, 5.6888037E-10, 36.1238141, 7.0666637168, 24986.0742741754, 4.5693825E-04, 7.5123334E-07, -3.5590172E-09, 30.7725751, 16.0827581417, 14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09, -28.3971008, 7.9982533891, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, -24.3582283, 10.3538079614, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10, -18.5847068, 2.8429122493, -557.3142796331, -1.8540681E-04, -2.1843765E-07, 1.0319744E-09, 17.9544674, 5.1553411398, 8399.6791003405, -3.5757942E-05, 3.2589854E-08, -2.0880440E-10, 14.5302779, 12.7956138971, 23243.1437596606, 8.8788511E-05, 3.1374165E-07, -1.4406287E-09, 14.3796974, 15.1080427876, 32200.1371396342, 2.3843738E-04, 5.6476915E-07, -2.6814075E-09, 14.2514576, -24.0810366320, -2.3011998397, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 13.8990596, 20.7938672862, 31085.5085803679, -1.3237624E-04, 1.2789385E-07, -6.1745870E-10, 13.1940636, 3.3302699264, -9443.3199839914, -5.2312637E-04, -6.8728642E-07, 3.2502879E-09, -9.6790568, -4.7542348263, -16029.0808942018, -3.0728938E-04, -5.0020584E-07, 2.3182384E-09, -9.3658635, 11.2971895604, 24080.9951807398, -3.4654346E-04, -1.9636409E-07, 9.1804319E-10, 8.6055318, 5.7289501804, -1742.9305145148, -3.6814974E-04, -4.3749170E-07, 2.1183885E-09, -8.4530982, 7.5540213938, 16100.0685698171, 1.1921869E-04, 2.8238458E-07, -1.3407038E-09, 8.0501724, 10.4831850066, 14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10, -7.6301553, 4.6679834628, 17285.6848046987, 3.0196162E-04, 5.0143862E-07, -2.4271179E-09, -7.4474952, -0.0862513635, 1256.6039104970, -5.3277630E-06, 1.2327842E-09, -1.0887946E-10, 7.3712011, 8.1276304344, 5957.4589549619, -2.1317311E-04, -1.8769697E-07, 9.8648918E-10, 7.0629900, 0.9591375719, 33.7570471374, -3.0829302E-05, -3.6967043E-08, 1.7385419E-10, -6.3831491, 9.4966777258, 7004.5133996281, 2.1416722E-04, 3.2425793E-07, -1.5355019E-09, -5.7416071, 13.6527441326, 32409.6866054649, -1.9423071E-04, 5.4047029E-08, -2.6829589E-10, 4.3740095, 18.4814383957, 22128.5152003943, -2.8202511E-04, -1.2313366E-07, 6.2332010E-10, -3.9976134, 7.9669196340, 33524.3151647312, 1.7658291E-04, 4.9092233E-07, -2.3322447E-09, -3.2096876, 13.2398458924, 14985.4400105508, -2.5159493E-04, -1.5449073E-07, 7.2324505E-10, -2.9145404, 12.7093625336, 24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09, 2.7318890, 16.1258838235, 13799.8237756692, -4.3433786E-04, -3.7354477E-07, 1.8096592E-09, -2.5679459, -2.4418059357, -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09, -2.5211990, 7.9551277074, 8470.6667759558, -2.2382863E-04, -1.8523141E-07, 7.6873027E-10, 2.4888871, 5.6426988169, -486.3266040178, -3.7347750E-04, -4.3625891E-07, 2.0095091E-09, 2.1460741, 7.1842488353, -1952.4799803455, 6.4518350E-05, 7.3230428E-08, -2.9472308E-10, 1.9777270, 23.1494218585, 39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09, 1.9336825, 9.4222182890, 33314.7656989005, 6.0925100E-04, 1.0016445E-06, -4.7453563E-09, 1.8707647, 20.8369929680, 30457.2066251194, -1.2971236E-04, 1.2727746E-07, -5.6301898E-10, -1.7529659, 0.4873576771, -8886.0057043583, -3.3771956E-04, -4.6884877E-07, 2.2183135E-09, -1.4371624, 7.0979974718, -695.8760698485, 5.9190587E-05, 7.4463212E-08, -4.0360254E-10, -1.3725701, 1.4552986550, -209.5494658307, 4.3266809E-04, 5.1072212E-07, -2.4131116E-09, 1.2618162, 7.5108957121, 16728.3705250656, 1.1655481E-04, 2.8300097E-07, -1.3951435E-09}; 39 | 40 | private static final double M11[] = {1.6768000, -0.0431256817, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, 0.5164200, 11.2260974062, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 0.4138300, 13.5816519784, 14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, 0.3711500, 5.5402729076, 7700.3894694766, 1.5497663E-04, 2.4979472E-07, -1.1318993E-09, 0.2756000, 2.3124288905, 8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 0.2459863, -25.6198212459, -2.3011998397, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 0.0711800, 7.9982533891, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, 0.0612800, 10.3538079614, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10}; 41 | 42 | private static final double M12[] = {0.0048700, -0.0431256817, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, 0.0022800, -27.1705318325, -2.3011998397, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, 0.0015000, 11.2260974062, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10}; 43 | 44 | private static final double M20[] = {18461.2400600, 1.6279052448, 8433.4661576405, -6.4021295E-05, -4.9499477E-09, 2.0216731E-11, 1010.1671484, 3.9834598170, 16762.1575823656, 8.8291456E-05, 2.4546117E-07, -1.1661223E-09, 999.6936555, 0.7276493275, -104.7747329154, 2.1633405E-04, 2.5536106E-07, -1.2065558E-09, 623.6524746, 8.7690283983, 7109.2881325435, -2.1668263E-06, 6.8896872E-08, -3.2894608E-10, 199.4837596, 9.6692843156, 15647.5290230993, -2.8252217E-04, -1.9141414E-07, 8.9782646E-10, 166.5741153, 6.4134738261, -1219.4032921817, -1.5447958E-04, -1.8151424E-07, 8.5739300E-10, 117.2606951, 12.0248388879, 23976.2204478244, -1.3020942E-04, 5.8996977E-08, -2.8851262E-10, 61.9119504, 6.3390143893, 25090.8490070907, 2.4060421E-04, 4.9587228E-07, -2.3524614E-09, 33.3572027, 11.1245829706, 15437.9795572686, 1.5014592E-04, 3.1930799E-07, -1.5152852E-09, 31.7596709, 3.0832038997, 8223.9166918098, 3.6864680E-04, 5.0577218E-07, -2.3928949E-09, 29.5766003, 8.8121540801, 6480.9861772950, 4.9705523E-07, 6.8280480E-08, -2.7450635E-10, 15.5662654, 4.0579192538, -9548.0947169068, -3.0679233E-04, -4.3192536E-07, 2.0437321E-09, 15.1215543, 14.3803934601, 32304.9118725496, 2.2103334E-05, 3.0940809E-07, -1.4748517E-09, -12.0941511, 8.7259027166, 7737.5900877920, -4.8307078E-06, 6.9513264E-08, -3.8338581E-10, 8.8681426, 9.7124099974, 15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10, 8.0450400, 0.6687636586, 8399.7091105030, -3.3191993E-05, 3.2017096E-08, -1.5363746E-10, 7.9585542, 12.0679645696, 23347.9184925760, -1.2754553E-04, 5.8380585E-08, -2.3407289E-10, 7.4345550, 6.4565995078, -1847.7052474301, -1.5181570E-04, -1.8213063E-07, 9.1183272E-10, -6.7314363, -4.0265854988, -16133.8556271171, -9.0955337E-05, -2.4484477E-07, 1.1116826E-09, 6.5795750, 16.8104074692, 14323.3509980023, -2.2066770E-04, -1.1756732E-07, 5.4866364E-10, -6.4600721, 1.5847795630, 9061.7681128890, -6.6685176E-05, -4.3335556E-09, -3.4222998E-11, -6.2964773, 4.8837157343, 25300.3984729215, -1.9206388E-04, -1.4849843E-08, 6.0650192E-11, -5.6323538, -0.7707750092, 733.0766881638, -2.1899793E-04, -2.5474467E-07, 1.1521161E-09, -5.3683961, 6.8263720663, 16204.8433027325, -9.7115356E-05, 2.7023515E-08, -1.3414795E-10, -5.3112784, 3.9403341353, 17390.4595376141, 8.5627574E-05, 2.4607756E-07, -1.2205621E-09, -5.0759179, 0.6845236457, 523.5272223331, 2.1367016E-04, 2.5597745E-07, -1.2609955E-09, -4.8396143, -1.6710309265, -7805.1642023920, 6.1357413E-05, 5.5663398E-09, -7.4656459E-11, -4.8057401, 3.5705615768, -662.0890125485, 3.0927234E-05, 3.6923410E-08, -1.7458141E-10, 3.9840545, 8.6945689615, 33419.5404318159, 3.9291696E-04, 7.4628340E-07, -3.5388005E-09, 3.6744619, 19.1659620415, 22652.0424227274, -6.8354947E-05, 1.3284380E-07, -6.3767543E-10, 2.9984815, 20.0662179587, 31190.2833132833, -3.4871029E-04, -1.2746721E-07, 5.8909710E-10, 2.7986413, -2.5281611620, -16971.7070481963, 3.4437664E-04, 2.6526096E-07, -1.2469893E-09, 2.4138774, 17.7106633865, 22861.5918885581, -5.0102304E-04, -3.7787833E-07, 1.7754362E-09, 2.1863132, 5.5132179088, -9757.6441827375, 1.2587576E-04, 7.8796768E-08, -3.6937954E-10, 2.1461692, 13.4801375428, 23766.6709819937, 3.0245868E-04, 5.6971910E-07, -2.7016242E-09, 1.7659832, 11.1677086523, 14809.6776020201, 1.5280981E-04, 3.1869159E-07, -1.4608454E-09, -1.6244212, 7.3137297434, 7318.8375983742, -4.3483492E-04, -4.4182525E-07, 2.0841655E-09, 1.5813036, 5.4387584720, 16552.6081165349, 5.2095955E-04, 7.5618329E-07, -3.5792340E-09, 1.5197528, 16.7359480324, 40633.6032972747, 1.7441609E-04, 5.5981921E-07, -2.6611908E-09, 1.5156341, 1.7023646816, -17876.7861416319, -4.5910508E-04, -6.8233647E-07, 3.2300712E-09, 1.5102092, 5.4977296450, 8399.6847301375, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, -1.3178223, 9.6261586339, 16275.8309783478, -2.8518605E-04, -1.9079775E-07, 8.4338673E-10, -1.2642739, 11.9817132061, 24604.5224030729, -1.3287330E-04, 5.9613369E-08, -3.4295235E-10, 1.1918723, 22.4217725310, 39518.9747380084, -1.9639754E-04, 1.2294390E-07, -5.9724197E-10, 1.1346110, 14.4235191419, 31676.6099173011, 2.4767216E-05, 3.0879170E-07, -1.4204120E-09, 1.0857810, 8.8552797618, 5852.6842220465, 3.1609367E-06, 6.7664088E-08, -2.2006663E-10, -1.0193852, 7.2392703065, 33629.0898976466, -3.9751134E-05, 2.3556127E-07, -1.1256889E-09, -0.8227141, 11.0814572888, 16066.2815125171, 1.4748204E-04, 3.1992438E-07, -1.5697249E-09, 0.8042238, 3.5274358950, -33.7870573000, 2.8263353E-05, 3.7539802E-08, -2.2902113E-10, 0.8025939, 6.7832463846, 16833.1452579809, -9.9779237E-05, 2.7639907E-08, -1.8858767E-10, -0.7931866, -6.3821400710, -24462.5470518423, -2.4326809E-04, -4.9525589E-07, 2.2980217E-09, -0.7910153, 6.3703481443, -591.1013369332, -1.5714346E-04, -1.8089785E-07, 8.0295327E-10, -0.6674056, 9.1819266386, 24533.5347274576, 5.5197395E-05, 2.7743463E-07, -1.3204870E-09, 0.6502226, 4.1010449356, -10176.3966721553, -3.0412845E-04, -4.3254175E-07, 2.0981718E-09, -0.6388131, 6.2958887075, 25719.1509623392, 2.3794032E-04, 4.9648867E-07, -2.4069012E-09}; 45 | 46 | private static final double M21[] = {0.0743000, 11.9537467337, 6480.9861772950, 4.9705523E-07, 6.8280480E-08, -2.7450635E-10, 0.0304300, 8.7259027166, 7737.5900877920, -4.8307078E-06, 6.9513264E-08, -3.8338581E-10, 0.0222900, 12.8540026510, 15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10, 0.0199900, 15.2095572232, 23347.9184925760, -1.2754553E-04, 5.8380585E-08, -2.3407289E-10, 0.0186900, 9.5981921614, -1847.7052474301, -1.5181570E-04, -1.8213063E-07, 9.1183272E-10, 0.0169600, 7.1681781524, 16133.8556271171, 9.0955337E-05, 2.4484477E-07, -1.1116826E-09, 0.0162300, 1.5847795630, 9061.7681128890, -6.6685176E-05, -4.3335556E-09, -3.4222998E-11, 0.0141900, -0.7707750092, 733.0766881638, -2.1899793E-04, -2.5474467E-07, 1.1521161E-09}; 47 | 48 | private static final double M30[] = {385000.5290396, 1.5707963268, 0.0000000000, 0.0000000E+00, 0.0000000E+00, 0.0000000E+00, -20905.3551378, 3.9263508990, 8328.6914247251, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09, -3699.1109330, 9.6121753977, 7214.0628654588, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10, -2955.9675626, 11.9677299699, 15542.7542901840, -6.6188121E-05, 6.3946925E-08, -3.0872935E-10, -569.9251264, 6.2819054713, 16657.3828494503, 3.0462550E-04, 5.0082223E-07, -2.3726782E-09, 246.1584797, 7.2566208254, -1114.6285592663, -3.7081362E-04, -4.3687530E-07, 2.0639488E-09, -204.5861179, 12.0108556517, 14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, -170.7330791, 14.3232845422, 23871.4457149091, 8.6124629E-05, 3.1435804E-07, -1.4950684E-09, -152.1378118, 9.6553010794, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, -129.6202242, -0.8278839272, -7700.3894694766, -1.5497663E-04, -2.4979472E-07, 1.1318993E-09, 108.7427014, 6.7692631483, 7771.3771450920, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10, 104.7552944, 3.8832252173, 8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 79.6605685, 0.6705404095, -8538.2408905558, 2.8035534E-04, 2.6031101E-07, -1.2267725E-09, 48.8883284, 1.5276706450, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, -34.7825237, 20.0091090408, 22756.8171556428, -2.8468899E-04, -1.2251727E-07, 5.6888037E-10, 30.8238599, 11.9246042882, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10, 24.2084985, 9.5690497159, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, -23.2104305, 8.6374600436, 24986.0742741754, 4.5693825E-04, 7.5123334E-07, -3.5590172E-09, -21.6363439, 17.6535544685, 14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09, -16.6747239, 6.7261374666, 8399.6791003405, -3.5757942E-05, 3.2589854E-08, -2.0880440E-10, 14.4026890, 4.9010662531, -9443.3199839914, -5.2312637E-04, -6.8728642E-07, 3.2502879E-09, -12.8314035, 14.3664102239, 23243.1437596606, 8.8788511E-05, 3.1374165E-07, -1.4406287E-09, -11.6499478, 22.3646636130, 31085.5085803679, -1.3237624E-04, 1.2789385E-07, -6.1745870E-10, -10.4447578, 16.6788391144, 32200.1371396342, 2.3843738E-04, 5.6476915E-07, -2.6814075E-09, 10.3211071, 8.7119194804, -1324.1780250970, 6.1854469E-05, 7.3846820E-08, -3.4916281E-10, 10.0562033, 7.2997465071, -1742.9305145148, -3.6814974E-04, -4.3749170E-07, 2.1183885E-09, -9.8844667, 12.0539813334, 14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10, 8.7515625, 6.3563649081, -9652.8694498221, -9.0458282E-05, -1.7656429E-07, 8.3717626E-10, -8.3791067, 4.4137085761, -557.3142796331, -1.8540681E-04, -2.1843765E-07, 1.0319744E-09, -7.0026961, -3.1834384995, -16029.0808942018, -3.0728938E-04, -5.0020584E-07, 2.3182384E-09, 6.3220032, 9.1248177206, 16100.0685698171, 1.1921869E-04, 2.8238458E-07, -1.3407038E-09, 5.7508579, 6.2387797896, 17285.6848046987, 3.0196162E-04, 5.0143862E-07, -2.4271179E-09, -4.9501349, 9.6984267611, 5957.4589549619, -2.1317311E-04, -1.8769697E-07, 9.8648918E-10, -4.4211770, 3.0260949818, -209.5494658307, 4.3266809E-04, 5.1072212E-07, -2.4131116E-09, 4.1311145, 11.0674740526, 7004.5133996281, 2.1416722E-04, 3.2425793E-07, -1.5355019E-09, -3.9579827, 20.0522347225, 22128.5152003943, -2.8202511E-04, -1.2313366E-07, 6.2332010E-10, 3.2582371, 14.8106422192, 14985.4400105508, -2.5159493E-04, -1.5449073E-07, 7.2324505E-10, -3.1483020, 4.8266068163, 16866.9323152810, -1.2804259E-04, -9.8998954E-09, 4.0433461E-11, 2.6164092, 14.2801588604, 24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09, 2.3536310, 9.5259240342, 8470.6667759558, -2.2382863E-04, -1.8523141E-07, 7.6873027E-10, -2.1171283, -0.8710096090, -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09, -1.8970368, 17.6966801503, 13799.8237756692, -4.3433786E-04, -3.7354477E-07, 1.8096592E-09, -1.7385258, 2.0581540038, -8886.0057043583, -3.3771956E-04, -4.6884877E-07, 2.2183135E-09, -1.5713944, 22.4077892948, 30457.2066251194, -1.2971236E-04, 1.2727746E-07, -5.6301898E-10, -1.4225541, 24.7202181853, 39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09, -1.4189284, 17.1661967915, 23314.1314352759, -9.9282182E-05, 9.5920387E-08, -4.6309403E-10, 1.1655364, 3.8400995356, 9585.2953352221, 1.4698499E-04, 2.5164390E-07, -1.2952185E-09, -1.1169371, 10.9930146158, 33314.7656989005, 6.0925100E-04, 1.0016445E-06, -4.7453563E-09, 1.0656723, 1.4845449633, 1256.6039104970, -5.3277630E-06, 1.2327842E-09, -1.0887946E-10, 1.0586190, 11.9220903668, 8364.7398411275, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10, -0.9333176, 9.0816920389, 16728.3705250656, 1.1655481E-04, 2.8300097E-07, -1.3951435E-09, 0.8624328, 12.4550876470, 6656.7485858257, -4.0390768E-04, -4.0490184E-07, 1.9095841E-09, 0.8512404, 4.3705828944, 70.9876756153, -1.8807069E-04, -2.1782126E-07, 9.7753467E-10, -0.8488018, 16.7219647962, 31571.8351843857, 2.4110126E-04, 5.6415276E-07, -2.6269678E-09, -0.7956264, 3.5134526588, -9095.5551701890, 9.4948529E-05, 4.1873358E-08, -1.9479814E-10}; 49 | 50 | private static final double M31[] = {0.5139500, 12.0108556517, 14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10, 0.3824500, 9.6553010794, 6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10, 0.3265400, 3.9694765808, 7700.3894694766, 1.5497663E-04, 2.4979472E-07, -1.1318993E-09, 0.2639600, 0.7416325637, 8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09, 0.1230200, -1.6139220085, 628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11, 0.0775400, 8.7830116346, 16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10, 0.0606800, 6.4274570623, 7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10, 0.0497000, 12.0539813334, 14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10}; 51 | 52 | private static final double M1n[] = {3.81034392032, 8.39968473021E+03, -3.31919929753E-05, 3.20170955005E-08, -1.53637455544E-10}; 53 | 54 | private static final double nutB[] = {2.1824391966, -33.757045954, 0.0000362262, 3.7340E-08, -2.8793E-10, -171996, -1742, 92025, 89, 3.5069406862, 1256.663930738, 0.0000105845, 6.9813E-10, -2.2815E-10, -13187, -16, 5736, -31, 1.3375032491, 16799.418221925, -0.0000511866, 6.4626E-08, -5.3543E-10, -2274, -2, 977, -5, 4.3648783932, -67.514091907, 0.0000724525, 7.4681E-08, -5.7586E-10, 2062, 2, -895, 5, 0.0431251803, -628.301955171, 0.0000026820, 6.5935E-10, 5.5705E-11, -1426, 34, 54, -1, 2.3555557435, 8328.691425719, 0.0001545547, 2.5033E-07, -1.1863E-09, 712, 1, -7, 0, 3.4638155059, 1884.965885909, 0.0000079025, 3.8785E-11, -2.8386E-10, -517, 12, 224, -6, 5.4382493597, 16833.175267879, -0.0000874129, 2.7285E-08, -2.4750E-10, -386, -4, 200, 0, 3.6930589926, 25128.109647645, 0.0001033681, 3.1496E-07, -1.7218E-09, -301, 0, 129, -1, 3.5500658664, 628.361975567, 0.0000132664, 1.3575E-09, -1.7245E-10, 217, -5, -95, 3}; 55 | 56 | private static final double GXC_e[] = {0.016708634, -0.000042037, -0.0000001267}; 57 | 58 | private static final double rad = 180 * 3600 / Math.PI; 59 | 60 | private static final double RAD = 180 / Math.PI; 61 | 62 | private static final double J2000 = 2451545; 63 | 64 | private static final double preceB[] = {0, 50287.92262, 111.24406, 0.07699, -0.23479, -0.00178, 0.00018, 0.00001}; 65 | 66 | private static final double GXC_p[] = {102.93735 / RAD, 1.71946 / RAD, 0.00046 / RAD}; 67 | 68 | private static final double GXC_l[] = {280.4664567 / RAD, 36000.76982779 / RAD, 0.0003032028 / RAD, 1 / 49931000 / RAD, -1 / 153000000 / RAD}; 69 | 70 | private static final double GXC_k = 20.49552 / rad; 71 | 72 | private static final double[] dts = {-4000, 108371.7, -13036.80, 392.000, 0.0000, -500, 17201.0, -627.82, 16.170, -0.3413, -150, 12200.6, -346.41, 5.403, -0.1593, 150, 9113.8, -328.13, -1.647, 0.0377, 500, 5707.5, -391.41, 0.915, 0.3145, 900, 2203.4, -283.45, 13.034, -0.1778, 1300, 490.1, -57.35, 2.085, -0.0072, 1600, 120.0, -9.81, -1.532, 0.1403, 1700, 10.2, -0.91, 0.510, -0.0370, 1800, 13.4, -0.72, 0.202, -0.0193, 1830, 7.8, -1.81, 0.416, -0.0247, 1860, 8.3, -0.13, -0.406, 0.0292, 1880, -5.4, 0.32, -0.183, 0.0173, 1900, -2.3, 2.06, 0.169, -0.0135, 1920, 21.2, 1.69, -0.304, 0.0167, 1940, 24.2, 1.22, -0.064, 0.0031, 1960, 33.2, 0.51, 0.231, -0.0109, 1980, 51.0, 1.29, -0.026, 0.0032, 2000, 64.7, -1.66, 5.224, -0.2905, 2150, 279.4, 732.95, 429.579, 0.0158, 6000}; 73 | 74 | private double EnnT = 0; 75 | private double MnnT = 0; 76 | 77 | private double D = 1; 78 | 79 | private class ZD { 80 | double Lon; 81 | double Obl; 82 | } 83 | 84 | /** 85 | * 生成某年农历二十四节气数组数据 86 | * Create solar term by year. 87 | * 88 | * @param year 某年 89 | * @return ... 90 | */ 91 | String[][] buildSolarTerm(int year) { 92 | String[] tmp = new String[24]; 93 | double jd = 365.2422 * (year - 2000), q; 94 | int j; 95 | for (int i = 0; i < tmp.length; i++) { 96 | j = (i - 5); 97 | q = angleCal(jd + j * 15.2, j * 15, 0); 98 | q = q + J2000 + (double) 8 / 24; 99 | setFromJD(q, true); 100 | tmp[i] = String.valueOf((int) D); 101 | } 102 | return DataUtils.arraysConvert(tmp, 12, 2); 103 | } 104 | 105 | private void setFromJD(double jd, boolean UTC) { 106 | if (UTC) 107 | jd -= this.deltaT2(jd - J2000); 108 | jd += 0.5; 109 | 110 | double A = int2(jd); 111 | double D; 112 | 113 | if (A > 2299161) { 114 | D = int2((A - 1867216.25) / 36524.25); 115 | A += 1 + D - int2(D / 4); 116 | } 117 | A += 1524; 118 | double y = int2((A - 122.1) / 365.25); 119 | D = A - int2(365.25 * y); 120 | double m = int2(D / 30.6001); 121 | this.D = D - int2(m * 30.6001); 122 | y -= 4716; 123 | m--; 124 | if (m > 12) 125 | m -= 12; 126 | if (m <= 2) 127 | //noinspection UnusedAssignment 128 | y++; 129 | } 130 | 131 | private double int2(double v) { 132 | v = Math.floor(v); 133 | if (v < 0) 134 | return v + 1; 135 | return v; 136 | } 137 | 138 | private double deltaT2(double jd) { 139 | return this.deltaT(jd / 365.2425 + 2000) / 86400.0; 140 | } 141 | 142 | private double deltaT(double y) { 143 | int i; 144 | for (i = 0; i < 100; i += 5) 145 | if (y < dts[i + 5] || i == 95) 146 | break; 147 | double t1 = (y - dts[i]) / (dts[i + 5] - dts[i]) * 10; 148 | double t2 = t1 * t1; 149 | double t3 = t2 * t1; 150 | return dts[i + 1] + dts[i + 2] * t1 + dts[i + 3] * t2 + dts[i + 4] * t3; 151 | } 152 | 153 | private double angleCal(double t1, double jiao, int lx) { 154 | double t2 = t1, t = 0, v; 155 | if (lx == 0) 156 | t2 += 360; 157 | else 158 | t2 += 25; 159 | jiao *= Math.PI / 180; 160 | double v1 = jiaoCai(lx, t1, jiao); 161 | double v2 = jiaoCai(lx, t2, jiao); 162 | if (v1 < v2) 163 | v2 -= 2 * Math.PI; 164 | double k = 1, k2; 165 | for (int i = 0; i < 10; i++) { 166 | k2 = (v2 - v1) / (t2 - t1); 167 | if (Math.abs(k2) > 1e-15) 168 | k = k2; 169 | t = t1 - v1 / k; 170 | v = jiaoCai(lx, t, jiao); 171 | if (v > 1) 172 | v -= 2 * Math.PI; 173 | if (Math.abs(v) < 1e-8) 174 | break; 175 | t1 = t2; 176 | v1 = v2; 177 | t2 = t; 178 | v2 = v; 179 | } 180 | return t; 181 | } 182 | 183 | private double jiaoCai(int lx, double t, double jiao) { 184 | double[] sun = earCal(t); 185 | sun[0] += Math.PI; 186 | sun[1] = -sun[1]; 187 | addGxc(t, sun); 188 | if (lx == 0) { 189 | ZD d = nutation(t); 190 | sun[0] += d.Lon; 191 | return rad2mrad(jiao - sun[0]); 192 | } 193 | double[] moon = moonCal(t); 194 | return rad2mrad(jiao - (moon[0] - sun[0])); 195 | } 196 | 197 | private double[] moonCal(double jd) { 198 | MnnT = jd / 36525; 199 | double t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1; 200 | double[] llr = new double[3]; 201 | llr[0] = (Mnn(M10) + Mnn(M11) * t1 + Mnn(M12) * t2) / rad; 202 | llr[1] = (Mnn(M20) + Mnn(M21) * t1) / rad; 203 | llr[2] = (Mnn(M30) + Mnn(M31) * t1) * 0.999999949827; 204 | llr[0] = llr[0] + M1n[0] + M1n[1] * t1 + M1n[2] * t2 + M1n[3] * t3 + M1n[4] * t4; 205 | llr[0] = rad2mrad(llr[0]); 206 | addPrece(jd, llr); 207 | return llr; 208 | } 209 | 210 | private void addPrece(double jd, double[] zb) { 211 | int i; 212 | double t = 1, v = 0, t1 = jd / 365250; 213 | for (i = 1; i < 8; i++) { 214 | t *= t1; 215 | v += preceB[i] * t; 216 | } 217 | zb[0] = rad2mrad(zb[0] + (v + 2.9965 * t1) / rad); 218 | } 219 | 220 | private double Mnn(double[] F) { 221 | double v = 0, t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1; 222 | for (int i = 0; i < F.length; i += 6) 223 | v += F[i] * Math.sin(F[i + 1] + t1 * F[i + 2] + t2 * F[i + 3] + t3 * F[i + 4] + t4 * F[i + 5]); 224 | return v; 225 | } 226 | 227 | private ZD nutation(double t) { 228 | ZD d = new ZD(); 229 | d.Lon = 0; 230 | d.Obl = 0; 231 | t /= 36525; 232 | double c, t1 = t, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1; 233 | for (int i = 0; i < nutB.length; i += 9) { 234 | c = nutB[i] + nutB[i + 1] * t1 + nutB[i + 2] * t2 + nutB[i + 3] * t3 + nutB[i + 4] * t4; 235 | d.Lon += (nutB[i + 5] + nutB[i + 6] * t / 10) * Math.sin(c); 236 | d.Obl += (nutB[i + 7] + nutB[i + 8] * t / 10) * Math.cos(c); 237 | } 238 | d.Lon /= rad * 10000; 239 | d.Obl /= rad * 10000; 240 | return d; 241 | } 242 | 243 | private void addGxc(double t, double[] zb) { 244 | double t1 = t / 36525; 245 | double t2 = t1 * t1; 246 | double t3 = t2 * t1; 247 | double t4 = t3 * t1; 248 | double L = GXC_l[0] + GXC_l[1] * t1 + GXC_l[2] * t2 + GXC_l[3] * t3 + GXC_l[4] * t4; 249 | double p = GXC_p[0] + GXC_p[1] * t1 + GXC_p[2] * t2; 250 | double e = GXC_e[0] + GXC_e[1] * t1 + GXC_e[2] * t2; 251 | double dL = L - zb[0], dP = p - zb[0]; 252 | zb[0] -= GXC_k * (Math.cos(dL) - e * Math.cos(dP)) / Math.cos(zb[1]); 253 | zb[1] -= GXC_k * Math.sin(zb[1]) * (Math.sin(dL) - e * Math.sin(dP)); 254 | zb[0] = rad2mrad(zb[0]); 255 | } 256 | 257 | private double[] earCal(double jd) { 258 | EnnT = jd / 365250; 259 | double llr[] = new double[3]; 260 | double t1 = EnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1, t5 = t4 * t1; 261 | llr[0] = Enn(E10) + Enn(E11) * t1 + Enn(E12) * t2 + Enn(E13) * t3 + Enn(E14) * t4 + Enn(E15) * t5; 262 | llr[1] = Enn(E20) + Enn(E21) * t1; 263 | llr[2] = Enn(E30) + Enn(E31) * t1 + Enn(E32) * t2 + Enn(E33) * t3; 264 | llr[0] = rad2mrad(llr[0]); 265 | return llr; 266 | } 267 | 268 | private double rad2mrad(double v) { 269 | v = v % (2 * Math.PI); 270 | if (v < 0) 271 | return v + 2 * Math.PI; 272 | return v; 273 | } 274 | 275 | private double Enn(double[] F) { 276 | double v = 0; 277 | for (int i = 0; i < F.length; i += 3) 278 | v += F[i] * Math.cos(F[i + 1] + EnnT * F[i + 2]); 279 | return v; 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysigndate/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysigndate; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.graphics.Canvas; 6 | import android.graphics.Paint; 7 | import android.graphics.Rect; 8 | import android.os.Bundle; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.view.View; 11 | import android.widget.Button; 12 | 13 | import com.wsg.mysign.mydatepicker.DPCManager; 14 | import com.wsg.mysign.mydatepicker.DPDecor; 15 | import com.wsg.mysign.mydatepicker.DPMode; 16 | import com.wsg.mysign.mydatepicker.DatePicker; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import butterknife.Bind; 22 | import butterknife.ButterKnife; 23 | 24 | public class MainActivity extends AppCompatActivity implements DatePicker.OnClickSignIn { 25 | 26 | @Bind(R.id.my_datepicker) 27 | DatePicker myDatepicker; 28 | @Bind(R.id.btn_original_demo) 29 | Button btnOriginalDemo; 30 | 31 | private Context mContext; 32 | 33 | private DPCManager dpcManager; 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_main); 39 | ButterKnife.bind(this); 40 | mContext = this; 41 | 42 | init(); 43 | 44 | btnOriginalDemo.setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View v) { 47 | startActivity(new Intent(mContext,YuanbanDemoActivity.class)); 48 | } 49 | }); 50 | } 51 | 52 | @Override 53 | protected void onResume() { 54 | super.onResume(); 55 | init(); 56 | } 57 | 58 | private void init() { 59 | dpcManager = DPCManager.getInstance(); 60 | dpcManager.clearnDATE_CACHE(); //清除cache 61 | 62 | //自定义背景绘制示例 63 | List tmp = new ArrayList<>(); 64 | tmp.add("2016-2-3"); //yyyy-M-d 65 | tmp.add("2016-2-1"); 66 | tmp.add("2016-2-9"); 67 | tmp.add("2016-2-10"); 68 | tmp.add("2016-2-11"); 69 | tmp.add("2016-2-12"); 70 | dpcManager.setDecorBG(tmp); //预先设置日期背景 一定要在在开始设置 71 | 72 | myDatepicker.setDate(2016, 2); //设置日期 73 | 74 | myDatepicker.setMode(DPMode.NONE); //设置选择模式 75 | 76 | myDatepicker.setFestivalDisplay(false); //是否显示节日 77 | myDatepicker.setTodayDisplay(false); //是否高亮显示今天 78 | myDatepicker.setHolidayDisplay(false); //是否显示假期 79 | myDatepicker.setDeferredDisplay(false); //是否显示补休 80 | myDatepicker.setIsScroll(false); //是否允许滑动 false表示左右上下都不能滑动 单项设置上下or左右 你需要自己扩展 81 | myDatepicker.setIsSelChangeColor(true, getResources().getColor(R.color.font_white_one)); //设置选择的日期字体颜色,不然有的背景颜色和默认的字体颜色不搭 82 | 83 | myDatepicker.setLeftTitle(2 + "月"); //左上方text 84 | myDatepicker.setRightTitle(false); //是否签到 85 | myDatepicker.setOnClickSignIn(this); //点击签到事件 86 | 87 | //设置预先选中日期的背景颜色 88 | myDatepicker.setDPDecor(new DPDecor() { 89 | @Override 90 | public void drawDecorBG(Canvas canvas, Rect rect, Paint paint) { 91 | paint.setColor(getResources().getColor(R.color.blue)); 92 | canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 4F, paint); 93 | } 94 | }); 95 | 96 | } 97 | 98 | @Override 99 | public void signIn() { 100 | //动态更新的时候必须 清除cache 101 | dpcManager.clearnDATE_CACHE(); //清除cache 102 | //重新设置日期 103 | List tmp = new ArrayList<>(); 104 | tmp.add("2016-2-20"); 105 | tmp.add("2016-2-21"); 106 | tmp.add("2016-2-22"); 107 | tmp.add("2016-2-25"); 108 | dpcManager.setDecorBG(tmp); 109 | 110 | myDatepicker.setDate(2016, 2); 111 | myDatepicker.setLeftTitle("2月"); 112 | myDatepicker.setRightTitle(true); 113 | 114 | myDatepicker.setDPDecor(new DPDecor() { 115 | @Override 116 | public void drawDecorBG(Canvas canvas, Rect rect, Paint paint) { 117 | paint.setColor(getResources().getColor(R.color.blue)); 118 | canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 4F, paint); 119 | } 120 | }); 121 | myDatepicker.invalidate(); //刷新 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/wsg/mysigndate/YuanbanDemoActivity.java: -------------------------------------------------------------------------------- 1 | package com.wsg.mysigndate; 2 | 3 | import android.app.AlertDialog; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.Rect; 8 | import android.os.Bundle; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.view.Gravity; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.view.Window; 14 | import android.view.WindowManager; 15 | import android.widget.Button; 16 | import android.widget.Toast; 17 | 18 | import com.wsg.mysign.mydatepicker.DPCManager; 19 | import com.wsg.mysign.mydatepicker.DPDecor; 20 | import com.wsg.mysign.mydatepicker.DPMode; 21 | import com.wsg.mysign.mydatepicker.DatePicker; 22 | import com.wsg.mysign.mydatepicker.DatePicker2; 23 | 24 | import java.util.ArrayList; 25 | import java.util.Iterator; 26 | import java.util.List; 27 | 28 | import butterknife.Bind; 29 | import butterknife.ButterKnife; 30 | 31 | /** 32 | * 原版demo 33 | */ 34 | public class YuanbanDemoActivity extends AppCompatActivity { 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_yuanban); 40 | 41 | // // 默认多选模式 42 | // DatePicker2 picker = (DatePicker2) findViewById(R.id.main_dp); 43 | // picker.setDate(2015, 7); 44 | // picker.setOnDateSelectedListener(new DatePicker.OnDateSelectedListener() { 45 | // @Override 46 | // public void onDateSelected(List date) { 47 | // String result = ""; 48 | // Iterator iterator = date.iterator(); 49 | // while (iterator.hasNext()) { 50 | // result += iterator.next(); 51 | // if (iterator.hasNext()) { 52 | // result += "\n"; 53 | // } 54 | // } 55 | // Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show(); 56 | // } 57 | // }); 58 | 59 | // 自定义背景绘制示例 Example of custom date's background 60 | List tmp = new ArrayList<>(); 61 | tmp.add("2015-7-1"); 62 | tmp.add("2015-7-8"); 63 | tmp.add("2015-7-16"); 64 | DPCManager.getInstance().setDecorBG(tmp); 65 | 66 | DatePicker2 picker = (DatePicker2) findViewById(R.id.main_dp); 67 | picker.setDate(2015, 7); 68 | picker.setDPDecor(new DPDecor() { 69 | @Override 70 | public void drawDecorBG(Canvas canvas, Rect rect, Paint paint) { 71 | paint.setColor(Color.RED); 72 | canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2F, paint); 73 | } 74 | }); 75 | picker.setOnDateSelectedListener(new DatePicker.OnDateSelectedListener() { 76 | @Override 77 | public void onDateSelected(List date) { 78 | String result = ""; 79 | Iterator iterator = date.iterator(); 80 | while (iterator.hasNext()) { 81 | result += iterator.next(); 82 | if (iterator.hasNext()) { 83 | result += "\n"; 84 | } 85 | } 86 | Toast.makeText(YuanbanDemoActivity.this, result, Toast.LENGTH_LONG).show(); 87 | } 88 | }); 89 | 90 | // 自定义前景装饰物绘制示例 Example of custom date's foreground decor 91 | List tmpTL = new ArrayList<>(); 92 | tmpTL.add("2015-10-5"); 93 | tmpTL.add("2015-10-6"); 94 | tmpTL.add("2015-10-7"); 95 | tmpTL.add("2015-10-8"); 96 | tmpTL.add("2015-10-9"); 97 | tmpTL.add("2015-10-10"); 98 | tmpTL.add("2015-10-11"); 99 | DPCManager.getInstance().setDecorTL(tmpTL); 100 | 101 | List tmpTR = new ArrayList<>(); 102 | tmpTR.add("2015-10-10"); 103 | tmpTR.add("2015-10-11"); 104 | tmpTR.add("2015-10-12"); 105 | tmpTR.add("2015-10-13"); 106 | tmpTR.add("2015-10-14"); 107 | tmpTR.add("2015-10-15"); 108 | tmpTR.add("2015-10-16"); 109 | DPCManager.getInstance().setDecorTR(tmpTR); 110 | 111 | // DatePicker2 picker = (DatePicker2) findViewById(R.id.main_dp); 112 | // picker.setDate(2015, 10); 113 | // picker.setFestivalDisplay(false); 114 | // picker.setTodayDisplay(false); 115 | // picker.setHolidayDisplay(false); 116 | // picker.setDeferredDisplay(false); 117 | // picker.setMode(DPMode.NONE); 118 | // picker.setDPDecor(new DPDecor() { 119 | // @Override 120 | // public void drawDecorTL(Canvas canvas, Rect rect, Paint paint, String data) { 121 | // super.drawDecorTL(canvas, rect, paint, data); 122 | // switch (data) { 123 | // case "2015-10-5": 124 | // case "2015-10-7": 125 | // case "2015-10-9": 126 | // case "2015-10-11": 127 | // paint.setColor(Color.GREEN); 128 | // canvas.drawRect(rect, paint); 129 | // break; 130 | // default: 131 | // paint.setColor(Color.RED); 132 | // canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2, paint); 133 | // break; 134 | // } 135 | // } 136 | // 137 | // @Override 138 | // public void drawDecorTR(Canvas canvas, Rect rect, Paint paint, String data) { 139 | // super.drawDecorTR(canvas, rect, paint, data); 140 | // switch (data) { 141 | // case "2015-10-10": 142 | // case "2015-10-11": 143 | // case "2015-10-12": 144 | // paint.setColor(Color.BLUE); 145 | // canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2, paint); 146 | // break; 147 | // default: 148 | // paint.setColor(Color.YELLOW); 149 | // canvas.drawRect(rect, paint); 150 | // break; 151 | // } 152 | // } 153 | // }); 154 | // picker.setOnDateSelectedListener(new DatePicker.OnDateSelectedListener() { 155 | // @Override 156 | // public void onDateSelected(List date) { 157 | // String result = ""; 158 | // Iterator iterator = date.iterator(); 159 | // while (iterator.hasNext()) { 160 | // result += iterator.next(); 161 | // if (iterator.hasNext()) { 162 | // result += "\n"; 163 | // } 164 | // } 165 | // Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show(); 166 | // } 167 | // }); 168 | 169 | // 对话框下的DatePicker示例 Example in dialog 170 | Button btnPick = (Button) findViewById(R.id.main_btn); 171 | btnPick.setOnClickListener(new View.OnClickListener() { 172 | @Override 173 | public void onClick(View v) { 174 | final AlertDialog dialog = new AlertDialog.Builder(YuanbanDemoActivity.this).create(); 175 | dialog.show(); 176 | DatePicker2 picker = new DatePicker2(YuanbanDemoActivity.this); 177 | picker.setDate(2015, 10); 178 | picker.setMode(DPMode.SINGLE); 179 | picker.setOnDatePickedListener(new DatePicker.OnDatePickedListener() { 180 | @Override 181 | public void onDatePicked(String date) { 182 | Toast.makeText(YuanbanDemoActivity.this, date, Toast.LENGTH_LONG).show(); 183 | dialog.dismiss(); 184 | } 185 | }); 186 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( 187 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 188 | dialog.getWindow().setContentView(picker, params); 189 | dialog.getWindow().setGravity(Gravity.CENTER); 190 | } 191 | }); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/box_blue_solid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 14 | 15 | 16 | 17 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/box_gray_solid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 14 | 15 | 16 | 17 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 18 | 19 | 20 | 25 | 26 | 27 |