diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 45a57aa8..fb7f4a8a 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,9 +1,6 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000..bfe22bea
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 0ad9e52f..55fa4b31 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,9 +4,10 @@
-
+
+
@@ -14,8 +15,6 @@
-
-
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index a5f05cd8..1d883acc 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -21,5 +21,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 2a39b99b..c61048e0 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,7 +5,7 @@
-
+
@@ -18,12 +18,13 @@
+
-
+
@@ -35,11 +36,12 @@
+
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 5e8a9652..a9062422 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,11 +2,15 @@
-
+
+
+
+
-
-
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d..00000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README-5.x.md b/README-5.x.md
new file mode 100644
index 00000000..89b28d26
--- /dev/null
+++ b/README-5.x.md
@@ -0,0 +1,224 @@
+# 安卓日历 NCalendar
+
+## 特点:
+
+ - 3种常见日历交互方式,MIUI系统日历:miui9、miui10、华为emui,miui9和钉钉日历类似,华为emui和365日历类似
+ - 月周滑动切换,月周不选中
+ - 支持多选,设置多选的数量
+ - 支持设置默认视图,默认周日历或者月日历
+ - 支持周状态固定,下拉刷新等
+ - 支持设置一周开始的是周一还是周日
+ - 可设置日期区间,默认区间从1901-01-01到2099-12-31
+ - 支持农历,节气、法定节假日等
+ - 支持添加指示点及设置指示点位置
+ - 支持各种颜色、距离、位置等属性
+ - 支持日历和列表之间添加view
+ - 支持替换农历、颜色等
+ - 支持自定义日历页面
+ - 支持内部TargetView为任意View
+ - 支持日历拉伸功能
+ - 支持适配器模式自定义日历
+
+## 效果图
+|Miui9Calendar|Miui10Calendar|EmuiCalendar|
+|:---:|:---:|:---:|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/miui9_gif.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/miui10_gif.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/emui_gif.gif)|
+
+|周固定,下拉刷新|日历和子view添加其他view|自定义日历界面(LigaturePainter)|
+|:---:|:---:|:---:|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/week_hold.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/addview.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/LigaturePainter.png)|
+
+|默认不选中|默认多选|自定义日历界面(TicketPainter)|
+|:---:|:---:|:---:|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/111.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/222.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/TicketPainter.png)|
+
+
+|ViewPager|普通View|demo功能预览|
+|:---:|:---:|:---:|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/viewpager.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/general.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/demo.png)|
+
+
+|日历拉伸|
+|:---:|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/Stretch.gif)|
+
+# 下载demo:
+[下载demo](https://github.com/yannecer/NCalendar/releases/download/4.3.0/4.3.0.apk)
+
+
+## 使用方法
+
+
+#### 项目build文件
+
+```
+ android {
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ ...
+ }
+
+```
+
+#### Gradle
+```
+implementation 'com.necer.ncalendar:ncalendar:5.0.2'
+
+```
+
+#### 简单使用
+
+```
+ miui9 和 钉钉日历
+
+ <
+
+
+ Miui10Calendar EmuiCalendar 用法类似
+
+```
+
+#### 单个月日历,单个周日历
+
+
+```
+ 月日历
+
+
+ 周日历
+
+
+```
+
+### [详细用法](https://github.com/yannecer/NCalendar/wiki/%E8%AF%A6%E7%BB%86%E7%94%A8%E6%B3%95)
+
+***
+
+## 自定义属性
+```
+5.x版本更新了大量的自定义属性
+```
+### [自定义属性](https://github.com/yannecer/NCalendar/wiki/%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7)
+
+***
+
+## 日历Api
+```
+日历提供了各种可能用到的方法、回调,5.x版本增加了日历日期变化的行为参数,区分了各种引起日历变化的不同的操作
+```
+### [日历Api](https://github.com/yannecer/NCalendar/wiki/%E6%97%A5%E5%8E%86Api)
+### [日历Api相关类说明](https://github.com/yannecer/NCalendar/wiki/Api%E7%9B%B8%E5%85%B3%E7%B1%BB%E8%AF%B4%E6%98%8E)
+
+***
+## 日历设置时间标记、替换文字等Api
+
+```
+日历设置时间标记、替换文字的Api,只对InnerPainter有效,如果是自定义日历UI,则这些方法需要自己实现,
+可参考InnerPainter相关代码
+
+```
+### [日历设置时间标记、替换文字](https://github.com/yannecer/NCalendar/wiki/%E6%97%A5%E5%8E%86%E8%AE%BE%E7%BD%AE%E6%A0%87%E8%AE%B0%E3%80%81%E6%9B%BF%E6%8D%A2%E6%96%87%E5%AD%97)
+***
+
+## 自定义日历UI
+```
+如果自定义属性不能满足日历ui要求,可以使用自定义页面实现个性化需求,项目提供了两种自定义UI的方式,
+1、实现CalendarPainter接口,通过Canvas绘制
+2、继承CalendarAdapter抽象类,和ListView的BaseAdapter用法相似
+```
+### [自定义日历UI](https://github.com/yannecer/NCalendar/wiki/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%8E%86UI)
+
+***
+
+
+### 交流群
+
+技术交流QQ群:127278900 (请先仔细看文档,然后再进群发问,上方加粗字体有下载demo链接)
+
+
+
+***
+### 常见问题
+```
+1、Activity初始化onCreate中调用jumpDate闪退
+ 页面初始化时,日历还未完成初始化,可以使用 setInitializeDate 方法完成初始页面的日期选定,或者使用日历对象post方法设置jumpdate
+ miui10Calendar.post(new Runnable() {
+ @Override
+ public void run() {
+ miui10Calendar.jumpDate("2021-01-01");
+ }
+ });
+
+2、日历UI问题,请使用自定义CalendarPainter,简单的做法是,复制库中InnerPainter,修改绘制的部分,然后给日历设置CalendarPainter
+ miui10Calendar.setCalendarPainter(myCalendarPainter);
+
+```
+
+## 感谢:
+
+项目中日期计算使用 [joda-time](https://github.com/JodaOrg/joda-time)
+感谢同事 **魏昌琳** 提出的优化建议
+感觉农历和节气数据工具类的作者
+
+
+***
+
+## 更新日志
+* 5.0.2 修复Android9日期变化回调多次的bug,增加2021年法定休班日
+* 5.0.1 修复2020年腊月二十九为除夕的描述
+* 5.0.0 重写InnerPainter,增加大量属性、优化跳转逻辑等
+* 4.4.1 新增跳转月份的方法
+* 4.4.0 新增适配器模式自定义页面
+* 4.3.8 新增月日历上下月是否可点击的属性 isLastNextMonthClickEnable
+* 4.3.7 修复选中月初月末,实际月份回调bug
+* 4.3.6 增加数字背景以及渐变效果
+* 4.3.4 修复周状态下滑动卡顿的bug
+* 4.3.3 修复莫名跳转2099年的bug,增加是否每个月都是6行的属性
+* 4.3.2 增加日历拉伸功能
+* 4.2.0 支持任意非滑动的View,ViewPger等
+* 4.1.2 完善LigaturePainter
+* 4.1.1 修改选中模式为枚举,demo增加了两种自定义CalendarPainter
+* 4.1.0 优化onDraw效率、修改CalendarPainter回调参数、新增多选日期数量
+* 4.0.4 修复某些情况下选中回调返回null的bug
+* 4.0.2 修复节气不显示的bug
+* 4.0.1 1、新增月周切换日历多选 2、新增默认不选中折叠 3、新增翻页默认选中每月1号 4、修复设置左右padding偏差
+
+
+
+
+
+
+License
+-------
+
+
+ Copyright 2018 necer
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
diff --git a/README.md b/README.md
index 5c2276bc..28bcc1fd 100644
--- a/README.md
+++ b/README.md
@@ -2,45 +2,45 @@
## 特点:
- - 3种常见日历交互方式,MIUI系统日历:miui9、miui10、华为emui,miui9和钉钉日历类似,华为emui和365日历类似
- - 月周滑动切换,月周不选中
- - 支持多选,设置多选的数量
- - 支持设置默认视图,默认周日历或者月日历
- - 支持周状态固定,下拉刷新等
- - 支持设置一周开始的是周一还是周日
- - 可设置日期区间,默认区间从1901-01-01到2099-12-31
- - 支持农历,节气、法定节假日等
- - 支持添加指示点及设置指示点位置
- - 支持各种颜色、距离、位置等属性
- - 支持日历和列表之间添加view
- - 支持替换农历、颜色等
- - 支持自定义日历页面
- - 支持内部TargetView为任意View
- - 支持日历拉伸功能
- - 支持适配器模式自定义日历
-
-## 效果图
-|Miui9Calendar|Miui10Calendar|EmuiCalendar|
-|:---:|:---:|:---:|
-|![](https://github.com/yannecer/NCalendar/blob/master/app/miui9_gif.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/miui10_gif.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/emui_gif.gif)|
+- 月日历、周日历、月周切换
+- 月周滑动切换,月周不选中
+- 支持多选,设置多选的数量
+- 支持设置默认视图,默认周日历或者月日历
+- 支持周状态固定,下拉刷新等
+- 支持设置一周开始的是周一还是周日
+- 可设置日期区间,默认区间从1901-01-01到2099-12-31
+- 支持农历,节气、法定节假日等
+- 支持添加指示点及设置指示点位置
+- 支持各种颜色、距离、位置等属性
+- 支持日历和列表之间添加view
+- 支持替换农历、颜色等
+- 支持自定义日历页面
+- 支持内部TargetView为任意View
+- 支持日历拉伸功能
+- 支持适配器模式自定义日历
+
+## 效果图
+| 效果1 | 效果2| 效果3|
+|:--------------------------------------------------------------------------------:|:--:|:---:|
+| ![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/miui9_gif.gif) |![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/miui10_gif.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/emui_gif.gif)|
|周固定,下拉刷新|日历和子view添加其他view|自定义日历界面(LigaturePainter)|
|:---:|:---:|:---:|
-|![](https://github.com/yannecer/NCalendar/blob/master/app/week_hold.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/addview.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/LigaturePainter.png)|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/week_hold.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/addview.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/LigaturePainter.png)|
|默认不选中|默认多选|自定义日历界面(TicketPainter)|
|:---:|:---:|:---:|
-|![](https://github.com/yannecer/NCalendar/blob/master/app/111.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/222.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/TicketPainter.png)|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/111.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/222.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/TicketPainter.png)|
|ViewPager|普通View|demo功能预览|
|:---:|:---:|:---:|
-|![](https://github.com/yannecer/NCalendar/blob/master/app/viewpager.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/general.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/demo.png)|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/viewpager.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/general.gif)|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/demo.png)|
|日历拉伸|
|:---:|
-|![](https://github.com/yannecer/NCalendar/blob/master/app/Stretch.gif)|
+|![](https://github.com/yannecer/NCalendar/blob/master/app/doc/pic/Stretch.gif)|
# 下载demo:
[下载demo](https://github.com/yannecer/NCalendar/releases/download/4.3.0/4.3.0.apk)
@@ -52,39 +52,24 @@
#### 项目build文件
```
- android {
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- ...
- }
```
#### Gradle
```
-implementation 'com.necer.ncalendar:ncalendar:5.0.2'
+
```
#### 简单使用
```
- miui9 和 钉钉日历
-
- <
-
-
- Miui10Calendar EmuiCalendar 用法类似
+ android:layout_height="match_parent" />
```
@@ -93,18 +78,20 @@ implementation 'com.necer.ncalendar:ncalendar:5.0.2'
```
月日历
-
+ android:layout_height="match_parent"
+ app:defaultCalendar="month"/>
周日历
-
+ android:layout_height="match_parent"
+ app:defaultCalendar="week"/>
```
-### [详细用法](https://github.com/yannecer/NCalendar/wiki/%E8%AF%A6%E7%BB%86%E7%94%A8%E6%B3%95)
+
***
@@ -170,14 +157,21 @@ implementation 'com.necer.ncalendar:ncalendar:5.0.2'
## 感谢:
-项目中日期计算使用 [joda-time](https://github.com/JodaOrg/joda-time)
-感谢同事 **魏昌琳** 提出的优化建议
-感觉农历和节气数据工具类的作者
+农历和节气数据工具类来自 [Hutool](https://github.com/dromara/hutool)
***
## 更新日志
+
+* 6.0.0 1、日历中日期使用```java.time.LocalDate```,因此```minSdkVersion```最低版本必须为```26```
+ 2、去除```MonthCalendar```和```WeekCalendar```,单独月日历和周日历整合进```NCalendar```
+ 3、动画切换改为```Draw```绘制
+ 4、加入阻断动画和快速滑动处理
+ 5、重构减少近半的代码量
+ 6、农历、节气等数据改为```Hutool```工具来
+ 7、去除```miui9```等几种动画效果,保留了最普遍的```Miui10```的效果
+
* 5.0.2 修复Android9日期变化回调多次的bug,增加2021年法定休班日
* 5.0.1 修复2020年腊月二十九为除夕的描述
* 5.0.0 重写InnerPainter,增加大量属性、优化跳转逻辑等
diff --git a/app/app-debug.apk b/app/app-debug.apk
deleted file mode 100644
index 483d2df1..00000000
Binary files a/app/app-debug.apk and /dev/null differ
diff --git a/app/build.gradle b/app/build.gradle
index db9ebb46..fdea7fa5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,36 +1,45 @@
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
android {
+ compileSdkVersion 34
+ buildToolsVersion "29.0.3"
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
-
- compileSdkVersion 28
defaultConfig {
- applicationId "com.necer.ncalendar"
- minSdkVersion 15
- targetSdkVersion 28
- versionCode 2
- versionName "5.0.1"
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ applicationId "com.necer.ncalendar.demo"
+ minSdkVersion 26
+ targetSdkVersion 34
+ versionCode 1
+ versionName "6.0.0"
+
}
+
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
}
dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.0'
- testImplementation 'junit:junit:4.12'
- implementation project(':ncalendar')
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.0.0'
-}
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
+ implementation project(path: ':ncalendar')
+
+}
\ No newline at end of file
diff --git a/app/doc/app/app-debug6.0.apk b/app/doc/app/app-debug6.0.apk
new file mode 100644
index 00000000..acbf5784
Binary files /dev/null and b/app/doc/app/app-debug6.0.apk differ
diff --git a/app/111.gif b/app/doc/pic/111.gif
similarity index 100%
rename from app/111.gif
rename to app/doc/pic/111.gif
diff --git a/app/222.gif b/app/doc/pic/222.gif
similarity index 100%
rename from app/222.gif
rename to app/doc/pic/222.gif
diff --git a/app/LigaturePainter.png b/app/doc/pic/LigaturePainter.png
similarity index 100%
rename from app/LigaturePainter.png
rename to app/doc/pic/LigaturePainter.png
diff --git a/app/Stretch.gif b/app/doc/pic/Stretch.gif
similarity index 100%
rename from app/Stretch.gif
rename to app/doc/pic/Stretch.gif
diff --git a/app/TicketPainter.png b/app/doc/pic/TicketPainter.png
similarity index 100%
rename from app/TicketPainter.png
rename to app/doc/pic/TicketPainter.png
diff --git a/app/add_view.png b/app/doc/pic/add_view.png
similarity index 100%
rename from app/add_view.png
rename to app/doc/pic/add_view.png
diff --git a/app/add_view1.png b/app/doc/pic/add_view1.png
similarity index 100%
rename from app/add_view1.png
rename to app/doc/pic/add_view1.png
diff --git a/app/addview.gif b/app/doc/pic/addview.gif
similarity index 100%
rename from app/addview.gif
rename to app/doc/pic/addview.gif
diff --git a/app/demo.png b/app/doc/pic/demo.png
similarity index 100%
rename from app/demo.png
rename to app/doc/pic/demo.png
diff --git a/app/emui_gif.gif b/app/doc/pic/emui_gif.gif
similarity index 100%
rename from app/emui_gif.gif
rename to app/doc/pic/emui_gif.gif
diff --git a/app/general.gif b/app/doc/pic/general.gif
similarity index 100%
rename from app/general.gif
rename to app/doc/pic/general.gif
diff --git a/app/miui10_gif.gif b/app/doc/pic/miui10_gif.gif
similarity index 100%
rename from app/miui10_gif.gif
rename to app/doc/pic/miui10_gif.gif
diff --git a/app/miui9_gif.gif b/app/doc/pic/miui9_gif.gif
similarity index 100%
rename from app/miui9_gif.gif
rename to app/doc/pic/miui9_gif.gif
diff --git a/app/month.png b/app/doc/pic/month.png
similarity index 100%
rename from app/month.png
rename to app/doc/pic/month.png
diff --git a/app/viewpager.gif b/app/doc/pic/viewpager.gif
similarity index 100%
rename from app/viewpager.gif
rename to app/doc/pic/viewpager.gif
diff --git a/app/week.png b/app/doc/pic/week.png
similarity index 100%
rename from app/week.png
rename to app/doc/pic/week.png
diff --git a/app/week_hold.gif b/app/doc/pic/week_hold.gif
similarity index 100%
rename from app/week_hold.gif
rename to app/doc/pic/week_hold.gif
diff --git a/app/src/androidTest/java/necer/ncalendardemo/ExampleInstrumentedTest.java b/app/src/androidTest/java/necer/ncalendardemo/ExampleInstrumentedTest.java
deleted file mode 100644
index c078844a..00000000
--- a/app/src/androidTest/java/necer/ncalendardemo/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package necer.ncalendardemo;
-
-import android.content.Context;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("necer.ncalendardemo", appContext.getPackageName());
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 583ff2e1..90bedf81 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,7 +11,8 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
-
+
@@ -70,18 +71,5 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/necer/ncalendar/TestActivity2.java b/app/src/main/java/com/necer/ncalendar/TestActivity2.java
index 62c383a3..d03265a3 100644
--- a/app/src/main/java/com/necer/ncalendar/TestActivity2.java
+++ b/app/src/main/java/com/necer/ncalendar/TestActivity2.java
@@ -2,16 +2,16 @@
import android.os.Bundle;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.MonthCalendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.listener.OnCalendarChangedListener;
-import org.joda.time.LocalDate;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
+import java.time.LocalDate;
+
/**
* Created by necer on 2020/3/24.
*/
@@ -23,12 +23,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity_test2);
- MonthCalendar monthCalendar = findViewById(R.id.monthCalendar);
+ NCalendar monthCalendar = findViewById(R.id.monthCalendar);
monthCalendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
}
+
});
}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/CustomCalendarActivity.java b/app/src/main/java/com/necer/ncalendar/activity/CustomCalendarActivity.java
index c193689b..b3e603d0 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/CustomCalendarActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/CustomCalendarActivity.java
@@ -5,23 +5,23 @@
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
-import com.necer.calendar.Miui10Calendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.CheckModel;
import com.necer.ncalendar.R;
import com.necer.ncalendar.painter.LigaturePainter;
import com.necer.ncalendar.painter.TicketPainter;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
/**
- * Created by necer on 2019/1/4.
+ * Created by necer on 2024/1/4.
*/
public class CustomCalendarActivity extends AppCompatActivity {
- Miui10Calendar miui10Calendar;
+ NCalendar miui10Calendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -37,25 +37,27 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
public void ligaturePainter(View view) {
LigaturePainter painter = new LigaturePainter(this);
miui10Calendar.setCalendarPainter(painter);
+ miui10Calendar.notifyCalendar();
}
public void ticketPainter(View view) {
TicketPainter ticketPainter = new TicketPainter(this, miui10Calendar);
Map priceMap = new HashMap<>();
- priceMap.put(new LocalDate("2019-06-07"), "¥350");
- priceMap.put(new LocalDate("2019-07-07"), "¥350");
- priceMap.put(new LocalDate("2019-06-30"), "¥350");
- priceMap.put(new LocalDate("2019-07-03"), "¥350");
- priceMap.put(new LocalDate("2019-07-04"), "¥350");
- priceMap.put(new LocalDate("2019-07-10"), "¥350");
- priceMap.put(new LocalDate("2019-07-15"), "¥350");
- priceMap.put(new LocalDate("2019-07-30"), "¥350");
- priceMap.put(new LocalDate("2019-08-04"), "¥350");
- priceMap.put(new LocalDate("2019-08-29"), "¥350");
+ priceMap.put(LocalDate.parse("2024-06-07"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-07"), "¥350");
+ priceMap.put(LocalDate.parse("2024-06-30"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-03"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-04"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-10"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-15"), "¥350");
+ priceMap.put(LocalDate.parse("2024-07-30"), "¥350");
+ priceMap.put(LocalDate.parse("2024-08-04"), "¥350");
+ priceMap.put(LocalDate.parse("2024-08-29"), "¥350");
ticketPainter.setPriceMap(priceMap);
miui10Calendar.setCalendarPainter(ticketPainter);
+ miui10Calendar.notifyCalendar();
}
}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/DingAdapterActivity.java b/app/src/main/java/com/necer/ncalendar/activity/DingAdapterActivity.java
deleted file mode 100644
index cc0d26ec..00000000
--- a/app/src/main/java/com/necer/ncalendar/activity/DingAdapterActivity.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.necer.ncalendar.activity;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.ICalendar;
-import com.necer.entity.CalendarDate;
-import com.necer.enumeration.CalendarType;
-import com.necer.enumeration.DateChangeBehavior;
-import com.necer.listener.OnCalendarChangedListener;
-import com.necer.ncalendar.R;
-import com.necer.painter.CalendarAdapter;
-import com.necer.utils.CalendarUtil;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
-public class DingAdapterActivity extends AppCompatActivity {
-
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.activity_adapter);
-
-
- ICalendar miui10Calendar = findViewById(R.id.miui10Calendar);
- miui10Calendar.setCalendarAdapter(new DingAdapter());
- // miui10Calendar.setSelectedMode(SelectedModel.MULTIPLE);
- miui10Calendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
- @Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
- Log.e("onCalendarChange", "onCalendarChange:::" + localDate);
- }
-
- });
-
- }
-
-
-
- public static class DingAdapter extends CalendarAdapter {
- @Override
- public View getCalendarItemView(Context context) {
- return LayoutInflater.from(context).inflate(R.layout.item_calendar, null);
- }
-
-
- @Override
- public void onBindToadyView(View view, LocalDate localDate, List totalCheckedDateList) {
-
- View ll_content = view.findViewById(R.id.ll_content);
-
- TextView tv_item = view.findViewById(R.id.tv_item);
-
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
-
- setLunar(view, localDate, totalCheckedDateList);
-
- if (totalCheckedDateList.contains(localDate)) {
- tv_item.setTextColor(Color.WHITE);
- ll_content.setBackgroundResource(R.drawable.bg_checked_ding);
- } else {
- tv_item.setTextColor(Color.BLACK);
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
- }
-
- @Override
- public void onBindCurrentMonthOrWeekView(View view, LocalDate localDate, List totalCheckedDateList) {
-
- View ll_content = view.findViewById(R.id.ll_content);
-
- TextView tv_item = view.findViewById(R.id.tv_item);
- tv_item.setTextColor(Color.BLACK);
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
-
- setLunar(view, localDate, totalCheckedDateList);
-
- if (totalCheckedDateList.contains(localDate)) {
- tv_item.setTextColor(Color.WHITE);
- ll_content.setBackgroundResource(R.drawable.bg_checked_ding);
- } else {
- tv_item.setTextColor(Color.BLACK);
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
-
- }
-
- @Override
- public void onBindLastOrNextMonthView(View view, LocalDate localDate, List totalCheckedDateList) {
- View ll_content = view.findViewById(R.id.ll_content);
- TextView tv_item = view.findViewById(R.id.tv_item);
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
- setLunar(view, localDate, totalCheckedDateList);
- if (totalCheckedDateList.contains(localDate)) {
- tv_item.setTextColor(Color.WHITE);
- ll_content.setBackgroundResource(R.drawable.bg_checked_ding_last_next);
- } else {
- tv_item.setTextColor(Color.GRAY);
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
- }
-
-
- private void setLunar(View view, LocalDate localDate, List selectedDateList) {
-
- TextView tv_lunar = view.findViewById(R.id.tv_lunar);
- CalendarDate calendarDate = CalendarUtil.getCalendarDate(localDate);
- tv_lunar.setText(calendarDate.lunar.lunarOnDrawStr);
- if (selectedDateList.contains(localDate)) {
- tv_lunar.setTextColor(Color.WHITE);
- } else {
- tv_lunar.setTextColor(Color.GRAY);
- }
- }
- }
-
-}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/GeneralAdapterActivity.java b/app/src/main/java/com/necer/ncalendar/activity/GeneralAdapterActivity.java
deleted file mode 100644
index 185ffe03..00000000
--- a/app/src/main/java/com/necer/ncalendar/activity/GeneralAdapterActivity.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.necer.ncalendar.activity;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.ICalendar;
-import com.necer.entity.CalendarDate;
-import com.necer.enumeration.DateChangeBehavior;
-import com.necer.listener.OnCalendarChangedListener;
-import com.necer.ncalendar.R;
-import com.necer.painter.CalendarAdapter;
-import com.necer.utils.CalendarUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
-public class GeneralAdapterActivity extends AppCompatActivity {
-
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.activity_adapter);
-
-
- ICalendar miui10Calendar = findViewById(R.id.miui10Calendar);
- miui10Calendar.setCalendarAdapter(new GeneralAdapter());
-
- miui10Calendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
- @Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
- Log.e("onCalendarChange", "onCalendarChange:::" + localDate);
- }
-
- });
-
- }
-
-
- public static class GeneralAdapter extends CalendarAdapter {
- @Override
- public View getCalendarItemView(Context context) {
- return LayoutInflater.from(context).inflate(R.layout.item_calendar, null);
- }
-
- @Override
- public void onBindToadyView(View view, LocalDate localDate, List totalCheckedDateList) {
-
- View ll_content = view.findViewById(R.id.ll_content);
-
- TextView tv_item = view.findViewById(R.id.tv_item);
- tv_item.setTextColor(Color.RED);
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
-
- setLunar(view, localDate);
- if (totalCheckedDateList.contains(localDate)) {
- ll_content.setBackgroundResource(R.drawable.bg_today_checked);
- } else {
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
-
- }
-
- @Override
- public void onBindCurrentMonthOrWeekView(View view, LocalDate localDate, List totalCheckedDateList) {
-
- View ll_content = view.findViewById(R.id.ll_content);
-
- TextView tv_item = view.findViewById(R.id.tv_item);
- tv_item.setTextColor(Color.BLACK);
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
-
- setLunar(view, localDate);
-
- if (totalCheckedDateList.contains(localDate)) {
- ll_content.setBackgroundResource(R.drawable.bg_checked);
- } else {
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
-
- }
-
- @Override
- public void onBindLastOrNextMonthView(View view, LocalDate localDate, List totalCheckedDateList) {
- View ll_content = view.findViewById(R.id.ll_content);
- TextView tv_item = view.findViewById(R.id.tv_item);
- tv_item.setTextColor(Color.GRAY);
- tv_item.setText(String.valueOf(localDate.getDayOfMonth()));
-
- setLunar(view, localDate);
- if (totalCheckedDateList.contains(localDate)) {
- ll_content.setBackgroundResource(R.drawable.bg_last_next_checked);
- } else {
- ll_content.setBackgroundResource(R.drawable.bg_unchecked);
- }
- }
-
-
- private void setLunar(View view, LocalDate localDate) {
- TextView tv_lunar = view.findViewById(R.id.tv_lunar);
- CalendarDate calendarDate = CalendarUtil.getCalendarDate(localDate);
- tv_lunar.setText(calendarDate.lunar.lunarOnDrawStr);
- }
- }
-
-}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/MainActivity.java b/app/src/main/java/com/necer/ncalendar/activity/MainActivity.java
index 9f7d32fd..6bdf06dd 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/MainActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/MainActivity.java
@@ -113,10 +113,6 @@ public void test(View view) {
startActivity(new Intent(this, TestActivity.class));
}
- public void testAdapter(View view) {
- startActivity(new Intent(this, TestAdapterActivity.class));
- }
-
private Intent getNewIntent(Class extends BaseActivity> clazz, CheckModel checkModel, String title) {
Intent intent = new Intent(this, clazz);
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestAdapterActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestAdapterActivity.java
deleted file mode 100644
index ccd8db61..00000000
--- a/app/src/main/java/com/necer/ncalendar/activity/TestAdapterActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.necer.ncalendar.activity;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-
-import com.necer.ncalendar.R;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
-public class TestAdapterActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_test_adapter);
- }
-
-
- public void general(View view) {
-
- startActivity(new Intent(this, GeneralAdapterActivity.class));
-
- }
-
- public void ding(View view) {
-
- startActivity(new Intent(this, DingAdapterActivity.class));
- }
-
-
-}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestAddViewActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestAddViewActivity.java
index f8596f28..93614e0c 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestAddViewActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestAddViewActivity.java
@@ -5,13 +5,13 @@
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
-import com.necer.calendar.Miui10Calendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.CalendarState;
import com.necer.ncalendar.R;
public class TestAddViewActivity extends AppCompatActivity {
- private Miui10Calendar miui10Calendar;
+ private NCalendar miui10Calendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestEmuiActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestEmuiActivity.java
index 642aba7f..230b182e 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestEmuiActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestEmuiActivity.java
@@ -6,16 +6,15 @@
import android.view.View;
import android.widget.TextView;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.EmuiCalendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.CalendarState;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.listener.OnCalendarChangedListener;
import com.necer.listener.OnCalendarMultipleChangedListener;
import com.necer.ncalendar.R;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
@@ -24,7 +23,7 @@
*/
public class TestEmuiActivity extends BaseActivity {
- private EmuiCalendar emuiCalendar;
+ private NCalendar emuiCalendar;
private TextView tv_result;
@@ -39,24 +38,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
tv_result = findViewById(R.id.tv_result);
emuiCalendar.setCheckMode(checkModel);
- emuiCalendar.setDefaultCheckedFirstDate(true);//只在selectedMode==SINGLE_SELECTED有效
emuiCalendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + localDate);
- Log.d(TAG, "当前页面选中::" + localDate);
- Log.e(TAG, "baseCalendar::" + baseCalendar);
}
});
emuiCalendar.setOnCalendarMultipleChangedListener(new OnCalendarMultipleChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + currPagerCheckedList.size() + "个 总共选中" + totalCheckedList.size() + "个");
- Log.d(TAG, year + "年" + month + "月");
- Log.d(TAG, "当前页面选中::" + currPagerCheckedList);
- Log.d(TAG, "全部选中::" + totalCheckedList);
}
});
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestMiui10Activity.java b/app/src/main/java/com/necer/ncalendar/activity/TestMiui10Activity.java
index 5296961f..75b35c8b 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestMiui10Activity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestMiui10Activity.java
@@ -2,6 +2,7 @@
import android.graphics.Color;
import android.graphics.drawable.Drawable;
+import android.icu.util.ChineseCalendar;
import android.os.Bundle;
import androidx.annotation.Nullable;
@@ -9,21 +10,17 @@
import android.util.Log;
import android.widget.TextView;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.Miui10Calendar;
-import com.necer.entity.CalendarDate;
-import com.necer.entity.Lunar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.enumeration.MultipleCountModel;
import com.necer.listener.OnCalendarChangedListener;
import com.necer.listener.OnCalendarMultipleChangedListener;
import com.necer.ncalendar.R;
-import com.necer.painter.CalendarBackground;
import com.necer.painter.InnerPainter;
-import com.necer.utils.CalendarUtil;
+import com.necer.utils.hutool.ChineseDate;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -36,7 +33,7 @@
*/
public class TestMiui10Activity extends BaseActivity {
- private Miui10Calendar miui10Calendar;
+ private NCalendar miui10Calendar;
private TextView tv_result;
private TextView tv_data;
@@ -93,17 +90,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
miui10Calendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + localDate);
- Log.d(TAG, " 当前页面选中 " + localDate);
- Log.d(TAG, " dateChangeBehavior " + dateChangeBehavior);
-
- Log.e(TAG, "baseCalendar::" + baseCalendar);
if (localDate != null) {
- CalendarDate calendarDate = CalendarUtil.getCalendarDate(localDate);
- Lunar lunar = calendarDate.lunar;
- tv_data.setText(localDate.toString("yyyy年MM月dd日"));
- tv_desc.setText(lunar.chineseEra + lunar.animals + "年" + lunar.lunarMonthStr + lunar.lunarDayStr);
+ ChineseDate chineseDate = new ChineseDate(localDate);
+ tv_data.setText(localDate.toString());
+ tv_desc.setText(chineseDate.getChineseZodiac() + chineseDate.getChineseYear() + "年" + chineseDate.getChineseMonth() + chineseDate.getChineseDay());
} else {
tv_data.setText("");
tv_desc.setText("");
@@ -113,7 +105,7 @@ public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, Loc
});
miui10Calendar.setOnCalendarMultipleChangedListener(new OnCalendarMultipleChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + currPagerCheckedList.size() + "个 总共选中" + totalCheckedList.size() + "个");
Log.d(TAG, year + "年" + month + "月");
Log.d(TAG, "当前页面选中::" + currPagerCheckedList);
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestMiui9Activity.java b/app/src/main/java/com/necer/ncalendar/activity/TestMiui9Activity.java
index 721574b3..65b88d8a 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestMiui9Activity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestMiui9Activity.java
@@ -8,8 +8,7 @@
import android.view.View;
import android.widget.TextView;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.Miui9Calendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.CalendarState;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.listener.OnCalendarChangedListener;
@@ -18,8 +17,8 @@
import com.necer.ncalendar.R;
import com.necer.ncalendar.adapter.RecyclerViewAdapter;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
@@ -29,7 +28,7 @@
public class TestMiui9Activity extends BaseActivity {
- private Miui9Calendar miui9Calendar;
+ private NCalendar miui9Calendar;
private TextView tv_result;
@@ -42,7 +41,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
miui9Calendar = findViewById(R.id.miui9Calendar);
- miui9Calendar.setCalendarState(CalendarState.WEEK);
miui9Calendar.setCheckMode(checkModel);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
@@ -53,30 +51,20 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
miui9Calendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + localDate);
- Log.e(TAG, "baseCalendar::" + baseCalendar);
}
+
});
miui9Calendar.setOnCalendarMultipleChangedListener(new OnCalendarMultipleChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + currPagerCheckedList.size() + "个 总共选中" + totalCheckedList.size() + "个");
- Log.d(TAG, year + "年" + month + "月");
- Log.d(TAG, "当前页面选中::" + currPagerCheckedList);
- Log.d(TAG, "全部选中::" + totalCheckedList);
- Log.e(TAG, "baseCalendar::" + baseCalendar);
}
- });
- miui9Calendar.setOnCalendarScrollingListener(new OnCalendarScrollingListener() {
- @Override
- public void onCalendarScrolling(float dy) {
- Log.d(TAG, "onCalendarScrolling::" + dy);
- }
});
}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestMonthActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestMonthActivity.java
index d2a51f68..57f6ea96 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestMonthActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestMonthActivity.java
@@ -9,23 +9,21 @@
import android.view.View;
import android.widget.TextView;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.MonthCalendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.listener.OnCalendarChangedListener;
import com.necer.listener.OnCalendarMultipleChangedListener;
import com.necer.ncalendar.R;
-import com.necer.painter.CalendarBackground;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
public class TestMonthActivity extends BaseActivity {
private TextView tv_result;
- private MonthCalendar monthCalendar;
+ private NCalendar monthCalendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -37,30 +35,22 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
monthCalendar = findViewById(R.id.monthCalendar);
monthCalendar.setCheckMode(checkModel);
- // monthCalendar.setDefaultSelectFirst(true);
-
-
-
monthCalendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + localDate);
Log.d(TAG, "setOnCalendarChangedListener:::" + year + "年" + month + "月" + " 当前页面选中 " + localDate);
- Log.e(TAG, "baseCalendar::" + baseCalendar);
}
+
});
monthCalendar.setOnCalendarMultipleChangedListener(new OnCalendarMultipleChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + currPagerCheckedList.size() + "个 总共选中" + totalCheckedList.size() + "个");
-
- Log.d(TAG, year + "年" + month + "月");
- Log.d(TAG, "当前页面选中::" + currPagerCheckedList);
- Log.d(TAG, "全部选中::" + totalCheckedList);
}
});
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestStretchActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestStretchActivity.java
index c7107364..6a600d0f 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestStretchActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestStretchActivity.java
@@ -4,7 +4,7 @@
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
-import com.necer.calendar.Miui10Calendar;
+import com.necer.calendar.NCalendar;
import com.necer.ncalendar.R;
import com.necer.painter.InnerPainter;
@@ -16,7 +16,7 @@
public class TestStretchActivity extends AppCompatActivity {
- private Miui10Calendar miui10Calendar;
+ private NCalendar miui10Calendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -24,7 +24,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity_stretch);
miui10Calendar = findViewById(R.id.miui10Calendar);
- miui10Calendar.setStretchCalendarEnable(true);
List pointList = Arrays.asList("2019-07-01", "2019-07-19", "2019-07-25", "2019-05-23", "2019-01-01", "2018-12-23");
@@ -33,12 +32,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
Map strMap = new HashMap<>();
- strMap.put("2019-07-01", "测试");
- strMap.put("2019-07-19", "测试1");
- strMap.put("2019-07-25", "测试2");
- strMap.put("2019-08-25", "测试3");
- strMap.put("2019-08-28", "测试4");
- strMap.put("2019-11-26", "测试5");
+ strMap.put("2024-07-01", "测试");
+ strMap.put("2024-07-19", "测试1");
+ strMap.put("2024-07-25", "测试2");
+ strMap.put("2024-08-25", "测试3");
+ strMap.put("2024-08-28", "测试4");
+ strMap.put("2024-11-26", "测试5");
innerPainter.setStretchStrMap(strMap);
}
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestWeekActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestWeekActivity.java
index f163edae..8b644763 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestWeekActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestWeekActivity.java
@@ -8,22 +8,21 @@
import android.view.View;
import android.widget.TextView;
-import com.necer.calendar.BaseCalendar;
-import com.necer.calendar.WeekCalendar;
+import com.necer.calendar.NCalendar;
import com.necer.enumeration.DateChangeBehavior;
import com.necer.listener.OnCalendarChangedListener;
import com.necer.listener.OnCalendarMultipleChangedListener;
import com.necer.ncalendar.R;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
public class TestWeekActivity extends BaseActivity {
private TextView tv_result;
- private WeekCalendar weekCalendar;
+ private NCalendar weekCalendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -32,23 +31,22 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
tv_result = findViewById(R.id.tv_result);
-
weekCalendar = findViewById(R.id.weekCalendar);
weekCalendar.setCheckMode(checkModel);
weekCalendar.setOnCalendarChangedListener(new OnCalendarChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + localDate);
Log.d(TAG, "setOnCalendarChangedListener:::" + year + "年" + month + "月" + " 当前页面选中 " + localDate);
- Log.e(TAG, "baseCalendar::" + baseCalendar);
}
+
});
weekCalendar.setOnCalendarMultipleChangedListener(new OnCalendarMultipleChangedListener() {
@Override
- public void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
+ public void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior) {
tv_result.setText(year + "年" + month + "月" + " 当前页面选中 " + currPagerCheckedList.size() + "个 总共选中" + totalCheckedList.size() + "个");
Log.d(TAG, year + "年" + month + "月");
diff --git a/app/src/main/java/com/necer/ncalendar/activity/TestWeekHoldActivity.java b/app/src/main/java/com/necer/ncalendar/activity/TestWeekHoldActivity.java
index 946f0c78..6c13d8a2 100644
--- a/app/src/main/java/com/necer/ncalendar/activity/TestWeekHoldActivity.java
+++ b/app/src/main/java/com/necer/ncalendar/activity/TestWeekHoldActivity.java
@@ -3,13 +3,14 @@
import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.Nullable;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
import android.view.View;
-import com.necer.calendar.Miui9Calendar;
+import com.necer.calendar.NCalendar;
import com.necer.ncalendar.R;
import com.necer.ncalendar.adapter.RecyclerViewAdapter;
@@ -23,7 +24,7 @@ public class TestWeekHoldActivity extends AppCompatActivity {
SwipeRefreshLayout refresh_layout;
RecyclerView recyclerView;
- Miui9Calendar miui9Calendar;
+ NCalendar miui9Calendar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
diff --git a/app/src/main/java/com/necer/ncalendar/painter/LigaturePainter.java b/app/src/main/java/com/necer/ncalendar/painter/LigaturePainter.java
index a1c78680..981e8559 100644
--- a/app/src/main/java/com/necer/ncalendar/painter/LigaturePainter.java
+++ b/app/src/main/java/com/necer/ncalendar/painter/LigaturePainter.java
@@ -7,15 +7,12 @@
import android.graphics.RectF;
import android.util.TypedValue;
-import com.necer.entity.CalendarDate;
import com.necer.ncalendar.DensityUtil;
import com.necer.painter.CalendarPainter;
-import com.necer.utils.CalendarUtil;
-import com.necer.view.CalendarView;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
+import com.necer.utils.NDateUtil;
+import com.necer.utils.hutool.ChineseDate;
+import java.time.LocalDate;
import java.util.List;
/**
@@ -81,16 +78,16 @@ private void drawSelectBg(Canvas canvas, RectF rectF, LocalDate localDate, boole
LocalDate nextLocalDate = localDate.plusDays(1);
if (selectedDateList.contains(localDate)) {
- if (selectedDateList.contains(lastLocalDate) && selectedDateList.contains(nextLocalDate) && CalendarUtil.isEqualsMonth(lastLocalDate, nextLocalDate)) {
+ if (selectedDateList.contains(lastLocalDate) && selectedDateList.contains(nextLocalDate) && NDateUtil.INSTANCE.isEqualsMonth(lastLocalDate, nextLocalDate)) {
//画全整个矩形
- RectF rectF1 = new RectF(rectF.left, rectF.centerY() - mCircleRadius, rectF.right, rectF.centerY() + mCircleRadius);
+ RectF rectF1 = new RectF(rectF.left - 1f, rectF.centerY() - mCircleRadius, rectF.right + 1f, rectF.centerY() + mCircleRadius);
mBgPaint.setAntiAlias(false);
mBgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawRect(rectF1, mBgPaint);
- } else if (selectedDateList.contains(lastLocalDate) && (!selectedDateList.contains(nextLocalDate) || !CalendarUtil.isEqualsMonth(nextLocalDate, localDate)) && CalendarUtil.isEqualsMonth(lastLocalDate, localDate)) {
+ } else if (selectedDateList.contains(lastLocalDate) && (!selectedDateList.contains(nextLocalDate) || !NDateUtil.INSTANCE.isEqualsMonth(nextLocalDate, localDate)) && NDateUtil.INSTANCE.isEqualsMonth(lastLocalDate, localDate)) {
//左矩形 右圆
- RectF rectF1 = new RectF(rectF.left, rectF.centerY() - mCircleRadius, rectF.centerX(), rectF.centerY() + mCircleRadius);
+ RectF rectF1 = new RectF(rectF.left- 1f, rectF.centerY() - mCircleRadius, rectF.centerX(), rectF.centerY() + mCircleRadius);
mBgPaint.setAntiAlias(false);
mBgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawRect(rectF1, mBgPaint);
@@ -104,9 +101,9 @@ private void drawSelectBg(Canvas canvas, RectF rectF, LocalDate localDate, boole
mBgPaint.setStyle(Paint.Style.STROKE);
canvas.drawArc(rectF2, -90, 180, false, mBgPaint);//右半圆弧
- } else if ((!selectedDateList.contains(lastLocalDate) || !CalendarUtil.isEqualsMonth(lastLocalDate, localDate)) && selectedDateList.contains(nextLocalDate) && CalendarUtil.isEqualsMonth(nextLocalDate, localDate)) {
+ } else if ((!selectedDateList.contains(lastLocalDate) || !NDateUtil.INSTANCE.isEqualsMonth(lastLocalDate, localDate)) && selectedDateList.contains(nextLocalDate) && NDateUtil.INSTANCE.isEqualsMonth(nextLocalDate, localDate)) {
//右矩形 左圆
- RectF rectF1 = new RectF(rectF.centerX(), rectF.centerY() - mCircleRadius, rectF.right, rectF.centerY() + mCircleRadius);
+ RectF rectF1 = new RectF(rectF.centerX(), rectF.centerY() - mCircleRadius, rectF.right+1f, rectF.centerY() + mCircleRadius);
mBgPaint.setAntiAlias(false);
mBgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawRect(rectF1, mBgPaint);
@@ -140,10 +137,10 @@ private void drawSolar(Canvas canvas, RectF rectF, LocalDate date, boolean isSel
//绘制农历
private void drawLunar(Canvas canvas, RectF rectF, LocalDate date, boolean isSelected, boolean isCurrectMonthOrWeek) {
mTextPaint.setTextSize(DensityUtil.dp2px(mContext, 10));
- CalendarDate calendarDate = CalendarUtil.getCalendarDate(date);
+ ChineseDate chineseDate = new ChineseDate(date);
mTextPaint.setColor(isSelected ? Color.WHITE : Color.GRAY);
mTextPaint.setAlpha(isCurrectMonthOrWeek ? 255 : 100);
- canvas.drawText(calendarDate.lunar.lunarOnDrawStr, rectF.centerX(), rectF.centerY() + DensityUtil.dp2px(mContext, 12), mTextPaint);
+ canvas.drawText(chineseDate.getChineseMonthName(), rectF.centerX(), rectF.centerY() + DensityUtil.dp2px(mContext, 12), mTextPaint);
}
diff --git a/app/src/main/java/com/necer/ncalendar/painter/StretchPainter.java b/app/src/main/java/com/necer/ncalendar/painter/StretchPainter.java
index b729ede9..d308fe84 100644
--- a/app/src/main/java/com/necer/ncalendar/painter/StretchPainter.java
+++ b/app/src/main/java/com/necer/ncalendar/painter/StretchPainter.java
@@ -9,12 +9,9 @@
import com.necer.ncalendar.DensityUtil;
import com.necer.painter.CalendarPainter;
-import com.necer.utils.CalendarUtil;
-import com.necer.view.CalendarView;
-import com.necer.view.ICalendarView;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
public class StretchPainter implements CalendarPainter {
diff --git a/app/src/main/java/com/necer/ncalendar/painter/TicketPainter.java b/app/src/main/java/com/necer/ncalendar/painter/TicketPainter.java
index e365a054..31718865 100644
--- a/app/src/main/java/com/necer/ncalendar/painter/TicketPainter.java
+++ b/app/src/main/java/com/necer/ncalendar/painter/TicketPainter.java
@@ -10,12 +10,8 @@
import com.necer.calendar.ICalendar;
import com.necer.ncalendar.DensityUtil;
import com.necer.painter.CalendarPainter;
-import com.necer.utils.CalendarUtil;
-import com.necer.view.CalendarView;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -52,14 +48,14 @@ public TicketPainter(Context context, ICalendar iCalendar) {
mHolidayList = new ArrayList<>();
mWorkdayList = new ArrayList<>();
- List holidayList = CalendarUtil.getHolidayList();
- for (int i = 0; i < holidayList.size(); i++) {
- mHolidayList.add(new LocalDate(holidayList.get(i)));
- }
- List workdayList = CalendarUtil.getWorkdayList();
- for (int i = 0; i < workdayList.size(); i++) {
- mWorkdayList.add(new LocalDate(workdayList.get(i)));
- }
+// List holidayList = CalendarUtil.getHolidayList();
+// for (int i = 0; i < holidayList.size(); i++) {
+// mHolidayList.add(new LocalDate(holidayList.get(i)));
+// }
+// List workdayList = CalendarUtil.getWorkdayList();
+// for (int i = 0; i < workdayList.size(); i++) {
+// mWorkdayList.add(new LocalDate(workdayList.get(i)));
+// }
}
diff --git a/app/src/main/res/layout/activity_adapter.xml b/app/src/main/res/layout/activity_adapter.xml
index ce3f4e22..3abb346f 100644
--- a/app/src/main/res/layout/activity_adapter.xml
+++ b/app/src/main/res/layout/activity_adapter.xml
@@ -6,13 +6,8 @@
android:orientation="vertical">
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_add_view.xml b/app/src/main/res/layout/activity_add_view.xml
index f8a10dfe..72e3368f 100644
--- a/app/src/main/res/layout/activity_add_view.xml
+++ b/app/src/main/res/layout/activity_add_view.xml
@@ -6,13 +6,7 @@
android:orientation="vertical">
-
-
-
@@ -62,5 +56,5 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_custom.xml b/app/src/main/res/layout/activity_custom.xml
index bb85b407..c75f23b4 100644
--- a/app/src/main/res/layout/activity_custom.xml
+++ b/app/src/main/res/layout/activity_custom.xml
@@ -25,13 +25,8 @@
-
-
-
@@ -58,7 +53,7 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_emui.xml b/app/src/main/res/layout/activity_emui.xml
index 0310b682..e4ca5a5d 100644
--- a/app/src/main/res/layout/activity_emui.xml
+++ b/app/src/main/res/layout/activity_emui.xml
@@ -61,12 +61,8 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_general.xml b/app/src/main/res/layout/activity_general.xml
index 4d483ceb..3f7bb9a5 100644
--- a/app/src/main/res/layout/activity_general.xml
+++ b/app/src/main/res/layout/activity_general.xml
@@ -5,11 +5,8 @@
android:orientation="vertical">
-
-
@@ -24,7 +21,7 @@
android:background="@color/colorAccent"
android:text="我只是一个TextView" />
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 3da51b0a..7b218d6d 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -77,21 +77,21 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="miui9_selected"
- android:text="miui9选中" />
+ android:text="日历1选中" />
+ android:text="日历1不选中" />
+ android:text="日历1多选" />
+ android:text="日历2选中" />
+ android:text="日历2不选中" />
+ android:text="日历2多选" />
@@ -130,21 +130,21 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="emiui_selected"
- android:text="emiui选中" />
+ android:text="日历3选中" />
+ android:text="日历3不选中" />
+ android:text="日历3多选" />
@@ -214,14 +214,6 @@
android:text="测试fragment"
android:textAllCaps="false" />
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_miui9.xml b/app/src/main/res/layout/activity_miui9.xml
index fcbf3c42..c2814e9a 100644
--- a/app/src/main/res/layout/activity_miui9.xml
+++ b/app/src/main/res/layout/activity_miui9.xml
@@ -82,12 +82,9 @@
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_month.xml b/app/src/main/res/layout/activity_month.xml
index 71292c31..b8642a11 100644
--- a/app/src/main/res/layout/activity_month.xml
+++ b/app/src/main/res/layout/activity_month.xml
@@ -2,6 +2,7 @@
@@ -14,15 +15,12 @@
android:padding="15dp" />
-
-
+ android:layout_height="match_parent"
+ app:defaultCalendar="month"/>
-
@@ -27,7 +27,7 @@
android:text="ceshi "/>
-
+
diff --git a/app/src/main/res/layout/activity_stretch.xml b/app/src/main/res/layout/activity_stretch.xml
index a866c0f7..b7dd9d4d 100644
--- a/app/src/main/res/layout/activity_stretch.xml
+++ b/app/src/main/res/layout/activity_stretch.xml
@@ -2,16 +2,14 @@
-
-
@@ -39,6 +37,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_test2.xml b/app/src/main/res/layout/activity_test2.xml
index 9f67dc4c..702efc87 100644
--- a/app/src/main/res/layout/activity_test2.xml
+++ b/app/src/main/res/layout/activity_test2.xml
@@ -6,7 +6,7 @@
android:orientation="vertical">
-
-
-
-
@@ -34,7 +30,7 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_week.xml b/app/src/main/res/layout/activity_week.xml
index 9f09ced4..de153510 100644
--- a/app/src/main/res/layout/activity_week.xml
+++ b/app/src/main/res/layout/activity_week.xml
@@ -14,14 +14,10 @@
android:padding="15dp" />
-
-
-
diff --git a/app/src/main/res/layout/activity_week_hold.xml b/app/src/main/res/layout/activity_week_hold.xml
index b78369c5..f119fa08 100644
--- a/app/src/main/res/layout/activity_week_hold.xml
+++ b/app/src/main/res/layout/activity_week_hold.xml
@@ -33,15 +33,10 @@
android:textSize="18sp" />
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment4.xml b/app/src/main/res/layout/fragment4.xml
index fe96bafd..921c185a 100644
--- a/app/src/main/res/layout/fragment4.xml
+++ b/app/src/main/res/layout/fragment4.xml
@@ -5,7 +5,7 @@
android:orientation="vertical">
-
@@ -27,6 +27,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/test/java/necer/ncalendardemo/ExampleUnitTest.java b/app/src/test/java/necer/ncalendardemo/ExampleUnitTest.java
deleted file mode 100644
index e9708e95..00000000
--- a/app/src/test/java/necer/ncalendardemo/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package necer.ncalendardemo;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index ef35ccf5..5d5c2372 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,35 +1,28 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
buildscript {
+ ext.kotlin_version = "1.3.72"
repositories {
- jcenter()
google()
+ maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+ jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.2'
-
- //上传jcenter相关插件
- classpath 'com.novoda:bintray-release:0.9.2'
-
+ classpath "com.android.tools.build:gradle:4.1.2"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
}
}
allprojects {
repositories {
- jcenter()
google()
+ maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+ jcenter()
}
-
-
- tasks.withType(Javadoc) {
- options.addStringOption('Xdoclint:none', '-quiet')
- options.addStringOption('encoding', 'UTF-8')
- }
-
}
task clean(type: Delete) {
delete rootProject.buildDir
-}
-
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c41dbe2e..1cecc3bc 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
+
diff --git a/ncalendar/build.gradle b/ncalendar/build.gradle
index 593ed9ac..1f43c8a6 100644
--- a/ncalendar/build.gradle
+++ b/ncalendar/build.gradle
@@ -1,34 +1,46 @@
-apply plugin: 'com.android.library'
-apply plugin: 'com.novoda.bintray-release'
+plugins {
+ id 'com.android.library'
+ id 'kotlin-android'
+}
android {
+ compileSdkVersion 34
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+
+ minSdkVersion 26
+ targetSdkVersion 34
+ versionCode 1
+ versionName "1.0"
+
+ consumerProguardFiles "consumer-rules.pro"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
-
- compileSdkVersion 28
- defaultConfig {
- minSdkVersion 15
- targetSdkVersion 28
- versionCode 1
- versionName "5.0.2"
+ kotlinOptions {
+ jvmTarget = '1.8'
}
}
dependencies {
- implementation 'androidx.appcompat:appcompat:1.0.0'
- api 'joda-time:joda-time:2.10.1'
-}
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ // implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ // implementation 'com.google.android.material:material:1.1.0'
+ // testImplementation 'junit:junit:4.+'
+ //androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+ //androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-publish {
- userOrg = 'necerr'//bintray.com用户名
- repoName = 'maven'//bintray仓库
- groupId = 'com.necer.ncalendar'//jcenter上的路径
- artifactId = 'ncalendar'//项目名称
- publishVersion = '5.0.2'//版本号
- desc = 'NCalendar'
- website = 'https://github.com/yannecer/NCalendar'
-}
+ //api 'cn.hutool:hutool-core:5.8.27'
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/adapter/BasePagerAdapter.java b/ncalendar/src/main/java/com/necer/adapter/BasePagerAdapter.java
deleted file mode 100644
index df02af97..00000000
--- a/ncalendar/src/main/java/com/necer/adapter/BasePagerAdapter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.necer.adapter;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.viewpager.widget.PagerAdapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.CalendarBuild;
-import com.necer.enumeration.CalendarType;
-import com.necer.view.CalendarView;
-import com.necer.view.CalendarView2;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
-
-/**
- * @author necer
- * @date 2017/8/25
- * QQ群:127278900
- */
-public abstract class BasePagerAdapter extends PagerAdapter {
-
-
- private Context mContext;
- private int mPageSize;
- private int mPageCurrIndex;
- private LocalDate mInitializeDate;
-
- private BaseCalendar mCalendar;
-
- BasePagerAdapter(Context context, BaseCalendar baseCalendar) {
- this.mContext = context;
- this.mCalendar = baseCalendar;
- this.mInitializeDate = baseCalendar.getInitializeDate();
- this.mPageSize = baseCalendar.getCalendarPagerSize();
- this.mPageCurrIndex = baseCalendar.getCalendarCurrIndex();
- }
-
- @Override
- public int getCount() {
- return mPageSize;
- }
-
-
- @Override
- public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
- return view == object;
- }
-
- @Override
- public void destroyItem(ViewGroup container, int position, @NonNull Object object) {
- container.removeView((View) object);
- }
-
-
- @NonNull
- @Override
- public Object instantiateItem(@NonNull ViewGroup container, int position) {
- ICalendarView iCalendarView;
- LocalDate pageInitializeDate = getPageInitializeDate(position);
- if (mCalendar.getCalendarBuild() == CalendarBuild.DRAW) {
- iCalendarView = new CalendarView(mContext, mCalendar, pageInitializeDate, getCalendarType());
- } else {
- iCalendarView = new CalendarView2(mContext, mCalendar, pageInitializeDate, getCalendarType());
- }
- ((View) iCalendarView).setTag(position);
- container.addView((View) iCalendarView);
- return iCalendarView;
- }
-
-
- int getPageCurrIndex() {
- return mPageCurrIndex;
- }
-
- LocalDate getInitializeDate() {
- return mInitializeDate;
- }
-
- public BaseCalendar getCalendar() {
- return mCalendar;
- }
-
-
- /**
- * 每个页面的初始化日期
- *
- * @param position 当前的position
- * @return 当前页面初始化的日期
- */
- protected abstract LocalDate getPageInitializeDate(int position);
-
- /**
- * 获取是周日历还是月日历
- *
- * @return MONTH->月 WEEK->周
- */
- protected abstract CalendarType getCalendarType();
-
-
-}
-
diff --git a/ncalendar/src/main/java/com/necer/adapter/GridCalendarAdapter.java b/ncalendar/src/main/java/com/necer/adapter/GridCalendarAdapter.java
deleted file mode 100644
index 5ece8eba..00000000
--- a/ncalendar/src/main/java/com/necer/adapter/GridCalendarAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.necer.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.BaseAdapter;
-
-import com.necer.view.CalendarView2;
-
-import java.util.List;
-/**
- * @author necer
- * QQ群:127278900
- */
-
-public class GridCalendarAdapter extends BaseAdapter {
-
- private List viewList;
-
- public GridCalendarAdapter(List viewList) {
- this.viewList = viewList;
- }
-
- @Override
- public int getCount() {
- return viewList.size();
- }
-
- @Override
- public Object getItem(int position) {
- return null;
- }
-
- @Override
- public long getItemId(int position) {
- return 0;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View calendarItemView = viewList.get(position);
- int realHeight = parent.getMeasuredHeight() - parent.getPaddingBottom() - parent.getPaddingTop();
- AbsListView.LayoutParams params = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, realHeight / (viewList.size() / 7));
- calendarItemView.setLayoutParams(params);
- ((CalendarView2) parent).bindView(position, calendarItemView);
- return calendarItemView;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/adapter/MonthPagerAdapter.java b/ncalendar/src/main/java/com/necer/adapter/MonthPagerAdapter.java
deleted file mode 100644
index dfb58cd3..00000000
--- a/ncalendar/src/main/java/com/necer/adapter/MonthPagerAdapter.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.necer.adapter;
-
-import android.content.Context;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.CalendarType;
-
-import org.joda.time.LocalDate;
-
-/**
- *
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public class MonthPagerAdapter extends BasePagerAdapter {
-
- public MonthPagerAdapter(Context context, BaseCalendar baseCalendar) {
- super(context, baseCalendar);
- }
-
- @Override
- protected LocalDate getPageInitializeDate(int position) {
- return getInitializeDate().plusMonths(position - getPageCurrIndex());
- }
-
- @Override
- protected CalendarType getCalendarType() {
- return CalendarType.MONTH;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/adapter/WeekPagerAdapter.java b/ncalendar/src/main/java/com/necer/adapter/WeekPagerAdapter.java
deleted file mode 100644
index a4cf68a6..00000000
--- a/ncalendar/src/main/java/com/necer/adapter/WeekPagerAdapter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.necer.adapter;
-
-import android.content.Context;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.CalendarType;
-
-import org.joda.time.LocalDate;
-
-/**
- *
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public class WeekPagerAdapter extends BasePagerAdapter {
-
-
- public WeekPagerAdapter(Context context, BaseCalendar baseCalendar) {
- super(context, baseCalendar);
- }
-
- @Override
- protected LocalDate getPageInitializeDate(int position) {
- return getInitializeDate().plusDays((position - getPageCurrIndex()) * 7);
- }
-
- @Override
- protected CalendarType getCalendarType() {
- return CalendarType.WEEK;
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/BaseCalendar.java b/ncalendar/src/main/java/com/necer/calendar/BaseCalendar.java
deleted file mode 100644
index a1f106e7..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/BaseCalendar.java
+++ /dev/null
@@ -1,646 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.Toast;
-
-import com.necer.R;
-import com.necer.adapter.BasePagerAdapter;
-import com.necer.enumeration.CalendarBuild;
-import com.necer.enumeration.DateChangeBehavior;
-import com.necer.enumeration.MultipleCountModel;
-import com.necer.enumeration.CheckModel;
-import com.necer.listener.OnCalendarChangedListener;
-import com.necer.listener.OnCalendarMultipleChangedListener;
-import com.necer.listener.OnClickDisableDateListener;
-import com.necer.listener.OnMWDateChangeListener;
-import com.necer.painter.CalendarAdapter;
-import com.necer.painter.CalendarBackground;
-import com.necer.painter.CalendarPainter;
-import com.necer.painter.InnerPainter;
-import com.necer.painter.NumBackground;
-import com.necer.painter.WhiteBackground;
-import com.necer.utils.Attrs;
-import com.necer.utils.AttrsUtil;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.viewpager.widget.ViewPager;
-
-/**
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public abstract class BaseCalendar extends ViewPager implements ICalendar {
-
-
- private Context mContext;
- private Attrs mAttrs;
- private boolean mScrollEnable = true;
- private CheckModel mCheckModel;//选中模式
- private final static String mDefaultStartDate = "1901-02-01";
- private final static String mDefaultEndDateDate = "2099-12-31";
-
- private boolean mDefaultCheckedFirstDate;//默认选择时,翻页选中第一个日期
-
- protected OnClickDisableDateListener mOnClickDisableDateListener;//点击区间之外的日期回调
- private OnMWDateChangeListener mOnMWDateChangeListener;//月周切换是折叠中心的回调
- private OnCalendarChangedListener mOnCalendarChangedListener;//单选时回调,当前页面无选中返回null
- private OnCalendarMultipleChangedListener mOnCalendarMultipleChangedListener;//多选时回调
-
- protected LocalDate mStartDate, mEndDate, mInitializeDate;
- protected CalendarPainter mCalendarPainter;
- private List mTotalCheckedDateList;
-
- private MultipleCountModel mMultipleCountModel;//多选数量模式
- private int mMultipleCount;//多选个数
-
- private int mFirstDayOfWeek;//日历的周一开始、周日开始
- private boolean mAllMonthSixLine;//月日历是否都是6行
-
- private CalendarBuild mCalendarBuild;
- private CalendarBackground mCalendarBackground;
-
- private CalendarAdapter mCalendarAdapter;
-
- private int mCalendarPagerSize;//日历总页数
- private int mCalendarCurrIndex;//日历当前页码
- private boolean mLastNextMonthClickEnable;//上下月是否可点击
-
- private DateChangeBehavior mDateChangeBehavior;
-
- public BaseCalendar(@NonNull Context context, @Nullable AttributeSet attributeSet) {
- super(context, attributeSet);
- this.mAttrs = AttrsUtil.getAttrs(context, attributeSet);
- this.mContext = context;
- mCheckModel = CheckModel.SINGLE_DEFAULT_CHECKED;
- mCalendarBuild = CalendarBuild.DRAW;
- mDateChangeBehavior = DateChangeBehavior.INITIALIZE;
- mTotalCheckedDateList = new ArrayList<>();
- mInitializeDate = new LocalDate();
- mStartDate = new LocalDate(mDefaultStartDate);
- mEndDate = new LocalDate(mDefaultEndDateDate);
-
- //背景
- if (mAttrs.showNumberBackground) {
- mCalendarBackground = new NumBackground(mAttrs.numberBackgroundTextSize, mAttrs.numberBackgroundTextColor, mAttrs.numberBackgroundAlphaColor);
- } else if (mAttrs.calendarBackground != null) {
- mCalendarBackground = (localDate, currentDistance, totalDistance) -> mAttrs.calendarBackground;
- } else {
- mCalendarBackground = new WhiteBackground();
- }
-
- mFirstDayOfWeek = mAttrs.firstDayOfWeek;
- mAllMonthSixLine = mAttrs.allMonthSixLine;
- mLastNextMonthClickEnable = mAttrs.lastNextMonthClickEnable;
-
- addOnPageChangeListener(new SimpleOnPageChangeListener() {
- @Override
- public void onPageSelected(final int position) {
- post(() -> drawView(position));
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- if (state == ViewPager.SCROLL_STATE_DRAGGING) {
- mDateChangeBehavior = DateChangeBehavior.PAGE;
- }
- }
- });
-
- initAdapter();
- }
-
-
- private void initAdapter() {
-
- if (mCheckModel == CheckModel.SINGLE_DEFAULT_CHECKED) {
- mTotalCheckedDateList.clear();
- mTotalCheckedDateList.add(mInitializeDate);
- }
-
- if (mStartDate.isAfter(mEndDate)) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_start_after_end));
- }
-
- if (mStartDate.isBefore(new LocalDate(mDefaultStartDate))) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_start_before_19010101));
- }
-
- if (mEndDate.isAfter(new LocalDate(mDefaultEndDateDate))) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_end_after_20991231));
- }
-
- if (mStartDate.isAfter(mInitializeDate) || mEndDate.isBefore(mInitializeDate)) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_initialize_date_illegal));
- }
-
- mCalendarPagerSize = getTwoDateCount(mStartDate, mEndDate, mFirstDayOfWeek) + 1;
- mCalendarCurrIndex = getTwoDateCount(mStartDate, mInitializeDate, mFirstDayOfWeek);
-
- BasePagerAdapter calendarAdapter = getPagerAdapter(mContext, this);
- setAdapter(calendarAdapter);
- setCurrentItem(mCalendarCurrIndex);
- }
-
-
- @Override
- public void setDateInterval(String startFormatDate, String endFormatDate) {
- try {
- mStartDate = new LocalDate(startFormatDate);
- mEndDate = new LocalDate(endFormatDate);
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_illegal));
- }
- initAdapter();
- }
-
- @Override
- public void setInitializeDate(String formatInitializeDate) {
- try {
- mInitializeDate = new LocalDate(formatInitializeDate);
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_illegal));
- }
- initAdapter();
- }
-
- @Override
- public void setDateInterval(String startFormatDate, String endFormatDate, String formatInitializeDate) {
- try {
- mStartDate = new LocalDate(startFormatDate);
- mEndDate = new LocalDate(endFormatDate);
- mInitializeDate = new LocalDate(formatInitializeDate);
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_illegal));
- }
- initAdapter();
- }
-
-
- private void drawView(int position) {
-
- ICalendarView iCalendarView = findViewWithTag(position);
-
- if (iCalendarView == null) {
- return;
- }
-
- //单选并且手势左右滑动、toNextPager、toLastPager 才需要处理这里的日期
- if (mCheckModel == CheckModel.SINGLE_DEFAULT_CHECKED && mDateChangeBehavior == DateChangeBehavior.PAGE) {
-
- //当前页面初始化的日期
- LocalDate pagerInitialDate = iCalendarView.getPagerInitialDate();
- //上个页面选中的日期
- LocalDate lastDate = mTotalCheckedDateList.get(0);
- //当前面页面的初始值和上个页选中的日期,相差几月或几周,
- int dateCount = getTwoDateCount(lastDate, pagerInitialDate, mFirstDayOfWeek);
- //再由上个页面选中的日期得出当前页面选中的日期
- LocalDate tempLocalDate = getIntervalDate(lastDate, dateCount);
- //当前页面需要选中的日期
- LocalDate currentDate;
- //默认选中第一个
- if (mDefaultCheckedFirstDate) {
- currentDate = getFirstDate();
- } else {
- currentDate = tempLocalDate;
- }
- //判断日期是否在有效日期之内
- LocalDate localDate = getAvailableDate(currentDate);
-
- mTotalCheckedDateList.clear();
- mTotalCheckedDateList.add(localDate);
- }
-
- iCalendarView.notifyCalendarView();
- callBack();
- }
-
-
- public void onClickCurrentMonthOrWeekDate(LocalDate localDate) {
- jump(localDate, true, DateChangeBehavior.CLICK);
- }
-
- public void onClickLastMonthDate(LocalDate localDate) {
- if (mLastNextMonthClickEnable && mScrollEnable) {
- jump(localDate, true, DateChangeBehavior.CLICK_PAGE);
- }
- }
-
- public void onClickNextMonthDate(LocalDate localDate) {
- if (mLastNextMonthClickEnable && mScrollEnable) {
- jump(localDate, true, DateChangeBehavior.CLICK_PAGE);
- }
- }
-
- protected void jump(LocalDate localDate, boolean isCheck, DateChangeBehavior dateChangeBehavior) {
- this.mDateChangeBehavior = dateChangeBehavior;
- //判断日期是否合法
- if (!isAvailable(localDate)) {
- if (getVisibility() == VISIBLE) {
- if (mOnClickDisableDateListener != null) {
- mOnClickDisableDateListener.onClickDisableDate(localDate);
- } else {
- Toast.makeText(getContext(), TextUtils.isEmpty(mAttrs.disabledString) ? getResources().getString(R.string.N_disabledString) : mAttrs.disabledString, Toast.LENGTH_SHORT).show();
- }
- }
- } else {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- //得出两个页面相差几个
- int indexOffset = getTwoDateCount(localDate, iCalendarView.getPagerInitialDate(), mFirstDayOfWeek);
- if (isCheck) {
- if (mCheckModel == CheckModel.MULTIPLE) {
- if (!mTotalCheckedDateList.contains(localDate)) {
- if (mTotalCheckedDateList.size() == mMultipleCount && mMultipleCountModel == MultipleCountModel.FULL_CLEAR) {
- mTotalCheckedDateList.clear();
- } else if (mTotalCheckedDateList.size() == mMultipleCount && mMultipleCountModel == MultipleCountModel.FULL_REMOVE_FIRST) {
- mTotalCheckedDateList.remove(0);
- }
- mTotalCheckedDateList.add(localDate);
- } else {
- mTotalCheckedDateList.remove(localDate);
- }
- } else {
- //单选
- mTotalCheckedDateList.clear();
- mTotalCheckedDateList.add(localDate);
- }
- }
-
- if (indexOffset == 0) {
- drawView(getCurrentItem());
- } else {
- setCurrentItem(getCurrentItem() - indexOffset, Math.abs(indexOffset) == 1);
- }
- }
- }
-
- private void callBack() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- LocalDate middleLocalDate = iCalendarView.getMiddleLocalDate();
- List currPagerCheckDateList = iCalendarView.getCurrPagerCheckDateList();
- LocalDate yearMonthLocalDate;
-
- if (BaseCalendar.this instanceof MonthCalendar) {
- //月日历返回初始化的月份
- yearMonthLocalDate = iCalendarView.getPagerInitialDate();
- } else {
- if (currPagerCheckDateList.size() == 0) {
- yearMonthLocalDate = middleLocalDate;
- } else {
- yearMonthLocalDate = currPagerCheckDateList.get(0);
- }
- }
-
- //月周折叠日历使用
- if (mOnMWDateChangeListener != null) {
- mOnMWDateChangeListener.onMwDateChange(BaseCalendar.this, iCalendarView.getPivotDate(), mTotalCheckedDateList);
- }
-
- //单选
- if (mOnCalendarChangedListener != null && mCheckModel != CheckModel.MULTIPLE && getVisibility() == VISIBLE) {
- mOnCalendarChangedListener.onCalendarChange(BaseCalendar.this, yearMonthLocalDate.getYear(), yearMonthLocalDate.getMonthOfYear(), currPagerCheckDateList.size() == 0 ? null : currPagerCheckDateList.get(0), mDateChangeBehavior);
- }
-
- //多选
- if (mOnCalendarMultipleChangedListener != null && mCheckModel == CheckModel.MULTIPLE && getVisibility() == VISIBLE) {
- mOnCalendarMultipleChangedListener.onCalendarChange(BaseCalendar.this, yearMonthLocalDate.getYear(), yearMonthLocalDate.getMonthOfYear(), currPagerCheckDateList, mTotalCheckedDateList, mDateChangeBehavior);
- }
- }
-
-
- @Override
- public void notifyCalendar() {
- for (int i = 0; i < getChildCount(); i++) {
- View childAt = getChildAt(i);
- if (childAt instanceof ICalendarView) {
- ICalendarView iCalendarView = (ICalendarView) childAt;
- iCalendarView.notifyCalendarView();
- }
- }
- }
-
- //日期边界处理
- private LocalDate getAvailableDate(LocalDate localDate) {
- if (localDate.isBefore(mStartDate)) {
- return mStartDate;
- } else if (localDate.isAfter(mEndDate)) {
- return mEndDate;
- } else {
- return localDate;
- }
- }
-
- @Override
- public void setOnClickDisableDateListener(OnClickDisableDateListener onClickDisableDateListener) {
- this.mOnClickDisableDateListener = onClickDisableDateListener;
- }
-
-
- @Override
- public void toNextPager() {
- mDateChangeBehavior = DateChangeBehavior.PAGE;
- setCurrentItem(getCurrentItem() + 1, true);
- }
-
- @Override
- public void toLastPager() {
- mDateChangeBehavior = DateChangeBehavior.PAGE;
- setCurrentItem(getCurrentItem() - 1, true);
- }
-
- @Override
- public void toToday() {
- jump(new LocalDate(), true, DateChangeBehavior.API);
- }
-
-
- @Override
- public void jumpDate(String formatDate) {
- LocalDate jumpDate;
- try {
- jumpDate = new LocalDate(formatDate);
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_illegal));
- }
-
- jump(jumpDate, true, DateChangeBehavior.API);
- }
-
-
- @Override
- public void jumpDate(int year, int month, int day) {
- LocalDate jumpDate;
- try {
- jumpDate = new LocalDate(year, month, day);
- } catch (Exception e) {
- throw new IllegalArgumentException("");
- }
- jump(jumpDate, true, DateChangeBehavior.API);
- }
-
- @Override
- public void jumpMonth(int year, int month) {
- LocalDate jumpDate;
- try {
- jumpDate = new LocalDate(year, month, 1);
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_jump));
- }
- jump(jumpDate, mCheckModel == CheckModel.SINGLE_DEFAULT_CHECKED, DateChangeBehavior.API);
- }
-
- @Override
- public List getTotalCheckedDateList() {
- return mTotalCheckedDateList;
- }
-
-
- @Override
- public void setCheckedDates(List dateList) {
-
- if (mCheckModel != CheckModel.MULTIPLE) {
- throw new RuntimeException(getContext().getString(R.string.N_set_checked_dates_illegal));
- }
-
- if (mMultipleCountModel != null && dateList.size() > mMultipleCount) {
- throw new RuntimeException(getContext().getString(R.string.N_set_checked_dates_count_illegal));
- }
- mTotalCheckedDateList.clear();
- try {
- for (int i = 0; i < dateList.size(); i++) {
- mTotalCheckedDateList.add(new LocalDate(dateList.get(i)));
- }
- } catch (Exception e) {
- throw new IllegalArgumentException(getContext().getString(R.string.N_date_format_illegal));
- }
- }
-
- //点击的日期是否可用
- public boolean isAvailable(LocalDate localDate) {
- return !localDate.isBefore(mStartDate) && !localDate.isAfter(mEndDate);
- }
-
-
- public LocalDate getInitializeDate() {
- return mInitializeDate;
- }
-
- public int getCalendarCurrIndex() {
- return mCalendarCurrIndex;
- }
-
- public int getCalendarPagerSize() {
- return mCalendarPagerSize;
- }
-
- public int getFirstDayOfWeek() {
- return mFirstDayOfWeek;
- }
-
- public boolean isAllMonthSixLine() {
- return mAllMonthSixLine;
- }
-
- public CalendarBuild getCalendarBuild() {
- return mCalendarBuild;
- }
-
- //设置绘制类
- @Override
- public void setCalendarPainter(CalendarPainter calendarPainter) {
- this.mCalendarBuild = CalendarBuild.DRAW;
- this.mCalendarPainter = calendarPainter;
- notifyCalendar();
- }
-
-
- @Override
- public void setCalendarAdapter(CalendarAdapter calendarAdapter) {
- this.mCalendarBuild = CalendarBuild.ADAPTER;
- this.mCalendarAdapter = calendarAdapter;
- notifyCalendar();
- }
-
- @Override
- public CalendarAdapter getCalendarAdapter() {
- return mCalendarAdapter;
- }
-
- @Override
- public CalendarPainter getCalendarPainter() {
- if (mCalendarPainter == null) {
- mCalendarPainter = new InnerPainter(getContext(), this);
- }
- return mCalendarPainter;
- }
-
-
- @Override
- public void updateSlideDistance(int currentDistance) {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- iCalendarView.updateSlideDistance(currentDistance);
- }
- }
-
- //月周切换时交换数据,保证月日历和周日历有相同的选中日期
- public void exchangeCheckedDateList(List dateList) {
- mTotalCheckedDateList.clear();
- mTotalCheckedDateList.addAll(dateList);
- notifyCalendar();
- }
-
-
- protected void setOnMWDateChangeListener(OnMWDateChangeListener onMWDateChangeListener) {
- this.mOnMWDateChangeListener = onMWDateChangeListener;
- }
-
- @Override
- public void setOnCalendarChangedListener(OnCalendarChangedListener onCalendarChangedListener) {
- this.mOnCalendarChangedListener = onCalendarChangedListener;
- }
-
- @Override
- public void setOnCalendarMultipleChangedListener(OnCalendarMultipleChangedListener onCalendarMultipleChangedListener) {
- this.mOnCalendarMultipleChangedListener = onCalendarMultipleChangedListener;
- }
-
- //获取当前月,当前周的第一个日期
- public LocalDate getFirstDate() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getCurrPagerFirstDate();
- }
- return null;
- }
-
-
- //获取PivotDate
- public LocalDate getPivotDate() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getPivotDate();
- }
- return null;
- }
-
- //localDate到顶部的距离
- public int getDistanceFromTop(LocalDate localDate) {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getDistanceFromTop(localDate);
- }
- return 0;
- }
-
- //PivotDate到顶部的距离
- public int getPivotDistanceFromTop() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getPivotDistanceFromTop();
- }
- return 0;
- }
-
- //回去viewpager的adapter
- protected abstract BasePagerAdapter getPagerAdapter(Context context, BaseCalendar baseCalendar);
-
- //两个日期的相差数量
- protected abstract int getTwoDateCount(LocalDate startDate, LocalDate endDate, int type);
-
- //相差count之后的的日期
- protected abstract LocalDate getIntervalDate(LocalDate localDate, int count);
-
-
- @Override
- public List getCurrPagerCheckDateList() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getCurrPagerCheckDateList();
- }
- return null;
- }
-
- @Override
- public List getCurrPagerDateList() {
- ICalendarView iCalendarView = findViewWithTag(getCurrentItem());
- if (iCalendarView != null) {
- return iCalendarView.getCurrPagerDateList();
- }
- return null;
- }
-
- @Override
- public Attrs getAttrs() {
- return mAttrs;
- }
-
-
- @Override
- public void setLastNextMonthClickEnable(boolean enable) {
- this.mLastNextMonthClickEnable = enable;
- }
-
- @Override
- public void setCheckMode(CheckModel checkModel) {
- this.mCheckModel = checkModel;
- mTotalCheckedDateList.clear();
- if (mCheckModel == CheckModel.SINGLE_DEFAULT_CHECKED) {
- mTotalCheckedDateList.add(mInitializeDate);
- }
- }
-
- @Override
- public CheckModel getCheckModel() {
- return mCheckModel;
- }
-
- @Override
- public void setDefaultCheckedFirstDate(boolean isDefaultCheckedFirstDate) {
- this.mDefaultCheckedFirstDate = isDefaultCheckedFirstDate;
- }
-
- @Override
- public void setMultipleCount(int multipleCount, MultipleCountModel multipleCountModel) {
- this.mCheckModel = CheckModel.MULTIPLE;
- this.mMultipleCountModel = multipleCountModel;
- this.mMultipleCount = multipleCount;
- }
-
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mScrollEnable) {
- return super.onInterceptTouchEvent(ev);
- } else {
- return false;
- }
- }
-
- @Override
- public void setScrollEnable(boolean scrollEnable) {
- this.mScrollEnable = scrollEnable;
- }
-
-
- @Override
- public void setCalendarBackground(CalendarBackground calendarBackground) {
- this.mCalendarBackground = calendarBackground;
- }
-
- @Override
- public CalendarBackground getCalendarBackground() {
- return mCalendarBackground;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/EmuiCalendar.java b/ncalendar/src/main/java/com/necer/calendar/EmuiCalendar.java
deleted file mode 100644
index 851abdc6..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/EmuiCalendar.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import android.util.AttributeSet;
-
-import com.necer.enumeration.CalendarState;
-
-import org.joda.time.LocalDate;
-
-/**
- * 仿华为日历
- *
- * @author necer
- * @date 2018/11/14
- */
-public class EmuiCalendar extends NCalendar {
- public EmuiCalendar(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected float getMonthCalendarAutoWeekEndY() {
- return -monthHeight * 4.0f / 5.0f;
- }
-
- @Override
- protected float getMonthYOnWeekState(LocalDate localDate) {
- return weekHeight - monthHeight;
- }
-
- @Override
- protected float getGestureMonthUpOffset(float dy) {
- return getGestureChildUpOffset(dy);
- }
-
- @Override
- protected float getGestureMonthDownOffset(float dy) {
- return getGestureChildDownOffset(dy);
- }
-
- @Override
- protected float getGestureChildDownOffset(float dy) {
- float maxOffset = monthHeight - childView.getY();
- return getOffset(Math.abs(dy), maxOffset);
- }
-
- @Override
- protected float getGestureChildUpOffset(float dy) {
- float maxOffset = childView.getY() - weekHeight;
- return getOffset(dy, maxOffset);
- }
-
-
- @Override
- protected void setWeekVisible(boolean isUp) {
-
- if (monthCalendar.getVisibility() != VISIBLE) {
- monthCalendar.setVisibility(VISIBLE);
- }
-
- if (calendarState == CalendarState.MONTH && isMonthCalendarWeekState() && isUp && weekCalendar.getVisibility() != VISIBLE) {
- weekCalendar.setVisibility(VISIBLE);
- } else if (calendarState == CalendarState.WEEK && monthCalendar.getY() <= -monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate()) && weekCalendar.getVisibility() != VISIBLE) {
- weekCalendar.setVisibility(VISIBLE);
- } else if (monthCalendar.getY() >= -monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate()) && !isUp && weekCalendar.getVisibility() != INVISIBLE) {
- weekCalendar.setVisibility(INVISIBLE);
- }
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/ICalendar.java b/ncalendar/src/main/java/com/necer/calendar/ICalendar.java
index 3d3342a9..5be1d139 100644
--- a/ncalendar/src/main/java/com/necer/calendar/ICalendar.java
+++ b/ncalendar/src/main/java/com/necer/calendar/ICalendar.java
@@ -1,17 +1,17 @@
package com.necer.calendar;
-import com.necer.enumeration.MultipleCountModel;
+
+import com.necer.enumeration.CalendarState;
import com.necer.enumeration.CheckModel;
+import com.necer.enumeration.MultipleCountModel;
import com.necer.listener.OnCalendarChangedListener;
import com.necer.listener.OnCalendarMultipleChangedListener;
+import com.necer.listener.OnCalendarStateChangedListener;
import com.necer.listener.OnClickDisableDateListener;
-import com.necer.painter.CalendarAdapter;
-import com.necer.painter.CalendarBackground;
import com.necer.painter.CalendarPainter;
-import com.necer.utils.Attrs;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
import java.util.List;
/**
@@ -19,6 +19,27 @@
*/
public interface ICalendar {
+
+ /**
+ * 回到周状态
+ */
+ void toWeek();
+
+ /**
+ * 回到月状态
+ */
+ void toMonth();
+
+ /**
+ * 回到拉伸状态
+ */
+ void toStretch();
+
+ /**
+ * 设置是否滑动到周位置固定
+ */
+ void setWeekHoldEnable(boolean isWeekHoldEnable);
+
/**
* 设置选中模式
*
@@ -43,12 +64,6 @@ public interface ICalendar {
void setMultipleCount(int multipleCount, MultipleCountModel multipleCountModel);
- /**
- * 默认选中时,是否翻页选中第一个,只在checkModel==SINGLE_DEFAULT_CHECKED有效
- */
- void setDefaultCheckedFirstDate(boolean isDefaultCheckedFirstDate);
-
-
/**
* 跳转日期
*
@@ -89,12 +104,6 @@ public interface ICalendar {
*/
void setCalendarPainter(CalendarPainter calendarPainter);
- /**
- * 设置自定义适配器 继承CalendarAdapter,实现对应方法,自定义
- *
- * @param calendarAdapter 继承抽象类CalendarAdapter
- */
- void setCalendarAdapter(CalendarAdapter calendarAdapter);
/**
* 刷新日历 刷新viewpager中存在的view
@@ -140,20 +149,12 @@ public interface ICalendar {
*/
void setOnClickDisableDateListener(OnClickDisableDateListener onClickDisableDateListener);
- /**
- * 获取xml参数
- */
- Attrs getAttrs();
/**
* 获取绘制类
*/
CalendarPainter getCalendarPainter();
- /**
- * 获取适配器
- */
- CalendarAdapter getCalendarAdapter();
/**
* 获取全部选中的日期集合
@@ -170,45 +171,25 @@ public interface ICalendar {
*/
List getCurrPagerDateList();
- /**
- * 月周折叠日历滑动过程中的滑动距离
- *
- * @param currentDistance 当前滑动的距离
- */
- void updateSlideDistance(int currentDistance);
-
- /**
- * 设置日历上下月能否点击
- */
- void setLastNextMonthClickEnable(boolean enable);
-
/**
- * 设置日历是否可以左右滑动
+ * 多选模式下,初始化时选中的日期
+ *
+ * @param dateList 日期几何 yyyy-MM-dd
*/
- void setScrollEnable(boolean scrollEnable);
+ void setCheckedDates(List dateList);
/**
- * @param calendarBackground 实现了CalendarBackground接口的背景
- * @throws IllegalAccessException 月周折叠日历不允许使用此方法
- * 折叠日历请调用setMonthCalendarBackground()和setWeekCalendarBackground()
+ * 日历月周状态变化回调
*/
- void setCalendarBackground(CalendarBackground calendarBackground) throws IllegalAccessException;
-
- /**
- * @return 获取日历的背景
- * @throws IllegalAccessException 月周折叠日历不允许使用此方法
- */
- CalendarBackground getCalendarBackground() throws IllegalAccessException;
+ void setOnCalendarStateChangedListener(OnCalendarStateChangedListener onCalendarStateChangedListener);
/**
- * 多选模式下,初始化时选中的日期
- *
- * @param dateList 日期几何 yyyy-MM-dd
+ * 获取日历状态
*/
- void setCheckedDates(List dateList);
+ CalendarState getCalendarState();
}
diff --git a/ncalendar/src/main/java/com/necer/calendar/IICalendar.java b/ncalendar/src/main/java/com/necer/calendar/IICalendar.java
deleted file mode 100644
index 2b190b74..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/IICalendar.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.necer.calendar;
-
-import com.necer.enumeration.CalendarState;
-import com.necer.listener.OnCalendarScrollingListener;
-import com.necer.listener.OnCalendarStateChangedListener;
-import com.necer.painter.CalendarBackground;
-
-/**
- * 折叠日历特有的功能接口
- * @author necer
- */
-public interface IICalendar extends ICalendar {
-
- /**
- * 回到周状态 只能从月->周
- */
- void toWeek();
-
- /**
- * 回到月状态 可以从周回到月或者从拉伸回到周
- */
- void toMonth();
-
- /**
- * 回到拉伸状态 只能从月->拉伸
- */
- void toStretch();
-
- /**
- * 设置是否滑动到周位置固定
- */
- void setWeekHoldEnable(boolean isWeekHoldEnable);
-
- /**
- * 设置月状态下 是否可以下拉拉伸
- */
- void setStretchCalendarEnable(boolean isMonthStretchEnable);
-
- /**
- * 日历月周状态变化回调
- */
- void setOnCalendarStateChangedListener(OnCalendarStateChangedListener onCalendarStateChangedListener);
-
- /**
- * 日历 月 周 拉伸 状态滑动监听
- */
- void setOnCalendarScrollingListener(OnCalendarScrollingListener onCalendarScrollingListener);
-
- /**
- * 设置日历状态
- *
- * @param calendarState WEEK 周
- * MONTH 月
- * MONTH_STRETCH 向下拉伸
- */
- void setCalendarState(CalendarState calendarState);
-
- /**
- * 获取当前日历的状态
- *
- * @return CalendarState.MONTH==月视图
- * CalendarState.WEEK==周视图
- * CalendarState.MONTH_STRETCH==日历拉伸状态
- */
- CalendarState getCalendarState();
-
-
- /**
- * 月周折叠日历设置月日历背景
- *
- * @param calendarBackground 实现了CalendarBackground接口的日历背景
- */
- void setMonthCalendarBackground(CalendarBackground calendarBackground);
-
- /**
- * 月周折叠日历设置周日历背景
- *
- * @param calendarBackground 实现了CalendarBackground接口的日历背景
- */
- void setWeekCalendarBackground(CalendarBackground calendarBackground);
-
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/Miui10Calendar.java b/ncalendar/src/main/java/com/necer/calendar/Miui10Calendar.java
deleted file mode 100644
index 73eacff5..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/Miui10Calendar.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import android.util.AttributeSet;
-
-import com.necer.enumeration.CalendarState;
-
-
-/**
- * 仿miui10日历
- *
- * @author necer
- * @date 2018/11/12
- */
-public class Miui10Calendar extends MiuiCalendar {
-
-
- public Miui10Calendar(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- */
- @Override
- protected float getGestureMonthUpOffset(float dy) {
- float maxOffset;
- float monthCalendarOffset;
- if (calendarState == CalendarState.MONTH) {
- maxOffset = monthCalendar.getPivotDistanceFromTop() - Math.abs(monthCalendar.getY());
- monthCalendarOffset = monthCalendar.getPivotDistanceFromTop();
- } else {
- maxOffset = monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate()) - Math.abs(monthCalendar.getY());
- monthCalendarOffset = monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate());
- }
- float childLayoutOffset = monthHeight - weekHeight;
- float offset = ((monthCalendarOffset * dy) / childLayoutOffset);
- return getOffset(offset, maxOffset);
- }
-
- /**
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- */
- @Override
- protected float getGestureMonthDownOffset(float dy) {
- float maxOffset = Math.abs(monthCalendar.getY());
- float monthCalendarOffset;
- if (calendarState == CalendarState.MONTH) {
- monthCalendarOffset = monthCalendar.getPivotDistanceFromTop();
- } else {
- monthCalendarOffset = monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate());
- }
- float childLayoutOffset = monthHeight - weekHeight;
- float offset = ((monthCalendarOffset * dy) / childLayoutOffset);
- return getOffset(Math.abs(offset), maxOffset);
- }
-
- @Override
- protected float getGestureChildDownOffset(float dy) {
- float maxOffset = monthHeight - childView.getY();
- return getOffset(Math.abs(dy), maxOffset);
- }
-
- @Override
- protected float getGestureChildUpOffset(float dy) {
- float maxOffset = childView.getY() - weekHeight;
- return getOffset(dy, maxOffset);
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/Miui9Calendar.java b/ncalendar/src/main/java/com/necer/calendar/Miui9Calendar.java
deleted file mode 100644
index ac779bb3..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/Miui9Calendar.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import android.util.AttributeSet;
-
-import com.necer.enumeration.CalendarState;
-
-/**
- * 仿miui9日历
- *
- * @author necer
- * @date 2018/11/7
- */
-public class Miui9Calendar extends MiuiCalendar {
-
- public Miui9Calendar(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected float getGestureMonthUpOffset(float dy) {
- float maxOffset;
- if (calendarState == CalendarState.MONTH) {
- //月 月日历有选中则选中为 中心点,如果没有选中则第一行
- maxOffset = monthCalendar.getPivotDistanceFromTop() - Math.abs(monthCalendar.getY());
- } else {
- //周的情况,按照周的第一个数据为中心点
- maxOffset = monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate()) - Math.abs(monthCalendar.getY());
- }
- return getOffset(dy, maxOffset);
- }
-
- @Override
- protected float getGestureMonthDownOffset(float dy) {
- float maxOffset = Math.abs(monthCalendar.getY());
- return getOffset(Math.abs(dy), maxOffset);
- }
-
- @Override
- protected float getGestureChildDownOffset(float dy) {
- float maxOffset = monthHeight - childView.getY();
- return getOffset(Math.abs(dy), maxOffset);
- }
-
- @Override
- protected float getGestureChildUpOffset(float dy) {
- float maxOffset = childView.getY() - weekHeight;
- return getOffset(dy, maxOffset);
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/MiuiCalendar.java b/ncalendar/src/main/java/com/necer/calendar/MiuiCalendar.java
deleted file mode 100644
index bce893c8..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/MiuiCalendar.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import android.util.AttributeSet;
-
-import com.necer.enumeration.CalendarState;
-
-import org.joda.time.LocalDate;
-
-
-/**
- * 仿miui日历抽象类
- *
- * @author necer
- * @date 2018/11/12
- */
-public abstract class MiuiCalendar extends NCalendar {
-
- public MiuiCalendar(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected float getMonthYOnWeekState(LocalDate localDate) {
- return -monthCalendar.getDistanceFromTop(localDate);
- }
-
- @Override
- protected float getMonthCalendarAutoWeekEndY() {
- float end;
- if (calendarState == CalendarState.MONTH) {
- //月 月日历有选中则选中为 中心点,如果没有选中则第一行
- end = -monthCalendar.getPivotDistanceFromTop();
- } else {
- //周的情况,按照周的第一个数据为中心点
- end = -monthCalendar.getDistanceFromTop(weekCalendar.getFirstDate());
- }
-
- return end;
- }
-
- @Override
- protected void setWeekVisible(boolean isUp) {
-
- if (isChildWeekState()) {
- if (weekCalendar.getVisibility() != VISIBLE) {
- weekCalendar.setVisibility(VISIBLE);
- }
-
- if (monthCalendar.getVisibility() != INVISIBLE) {
- monthCalendar.setVisibility(INVISIBLE);
- }
-
- } else {
- if (weekCalendar.getVisibility() != INVISIBLE) {
- weekCalendar.setVisibility(INVISIBLE);
- }
-
- if (monthCalendar.getVisibility() != VISIBLE) {
- monthCalendar.setVisibility(VISIBLE);
- }
- }
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/MonthCalendar.java b/ncalendar/src/main/java/com/necer/calendar/MonthCalendar.java
deleted file mode 100644
index 930dae26..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/MonthCalendar.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import android.util.AttributeSet;
-
-import com.necer.adapter.BasePagerAdapter;
-import com.necer.adapter.MonthPagerAdapter;
-import com.necer.enumeration.CalendarBuild;
-import com.necer.utils.Attrs;
-import com.necer.utils.CalendarUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-/**
- *
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public class MonthCalendar extends BaseCalendar {
-
- public MonthCalendar(@NonNull Context context, @Nullable AttributeSet attributeSet) {
- super(context, attributeSet);
- }
-
- @Override
- protected BasePagerAdapter getPagerAdapter(Context context, BaseCalendar baseCalendar) {
- return new MonthPagerAdapter(context,baseCalendar);
- }
-
- @Override
- protected int getTwoDateCount(LocalDate startDate, LocalDate endDate, int type) {
- return CalendarUtil.getIntervalMonths(startDate, endDate);
- }
-
- @Override
- protected LocalDate getIntervalDate(LocalDate localDate, int count) {
- return localDate.plusMonths(count);
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/NCalendar.java b/ncalendar/src/main/java/com/necer/calendar/NCalendar.java
deleted file mode 100644
index cd378260..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/NCalendar.java
+++ /dev/null
@@ -1,955 +0,0 @@
-package com.necer.calendar;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.view.NestedScrollingParent;
-
-import android.util.AttributeSet;
-
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.necer.R;
-import com.necer.enumeration.CalendarState;
-import com.necer.enumeration.DateChangeBehavior;
-import com.necer.enumeration.MultipleCountModel;
-import com.necer.enumeration.CheckModel;
-import com.necer.listener.OnCalendarChangedListener;
-import com.necer.listener.OnCalendarMultipleChangedListener;
-import com.necer.listener.OnCalendarScrollingListener;
-import com.necer.listener.OnCalendarStateChangedListener;
-import com.necer.listener.OnClickDisableDateListener;
-import com.necer.listener.OnEndAnimatorListener;
-import com.necer.listener.OnMWDateChangeListener;
-import com.necer.painter.CalendarAdapter;
-import com.necer.painter.CalendarBackground;
-import com.necer.painter.CalendarPainter;
-import com.necer.painter.InnerPainter;
-import com.necer.painter.NumBackground;
-import com.necer.painter.WhiteBackground;
-import com.necer.utils.Attrs;
-import com.necer.utils.AttrsUtil;
-import com.necer.utils.ViewUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-
-/**
- * Created by necer on 2018/11/12.
- */
-public abstract class NCalendar extends FrameLayout implements IICalendar, NestedScrollingParent, ValueAnimator.AnimatorUpdateListener {
-
- protected WeekCalendar weekCalendar;
- protected MonthCalendar monthCalendar;
-
- //周日历的高度
- protected int weekHeight;
- //月日历的高度,是日历整个的高
- protected int monthHeight;
- //月日历拉伸的高度
- protected int stretchMonthHeight;
- //日历状态,默认月
- protected CalendarState calendarState;
- private OnCalendarStateChangedListener onCalendarStateChangedListener;
- private OnCalendarScrollingListener onCalendarScrollingListener;
-
- protected View childView;//NCalendar内部包含的直接子view,直接子view并不一定是NestScrillChild
- private View targetView;//实际滑动的view 当targetView==null时,子view没有NestScrillChild或者NestScrillChild不可见,此时滑动交给onTochEvent处理
-
- protected RectF monthRect;//月日历大小的矩形
- protected RectF weekRect;//周日历大小的矩形 ,用于判断点击事件是否在日历的范围内
- protected RectF stretchMonthRect;
-
- private boolean isWeekHoldEnable;//是否需要周状态定
- private boolean isStretchCalendarEnable;//月日历是否可拉伸
-
- private boolean isInflateFinish;//是否加载完成,
-
- protected ValueAnimator monthValueAnimator;//月日历动画
- protected ValueAnimator monthStretchValueAnimator;//月日历动画
- protected ValueAnimator childViewValueAnimator;
-
- private final Attrs attrs;
-
- public NCalendar(@NonNull Context context, @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public NCalendar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
-
- setMotionEventSplittingEnabled(false);
- this.attrs = AttrsUtil.getAttrs(context, attrs);
-
- int duration = this.attrs.animationDuration;
- monthHeight = this.attrs.calendarHeight;
- isStretchCalendarEnable = this.attrs.stretchCalendarEnable;
- stretchMonthHeight = this.attrs.stretchCalendarHeight;
-
- if (monthHeight >= stretchMonthHeight) {
- throw new RuntimeException(getContext().getString(R.string.N_stretch_month_height));
- }
-
- calendarState = CalendarState.valueOf(this.attrs.defaultCalendar);
- weekHeight = monthHeight / 5;
-
- monthCalendar = new MonthCalendar(context, attrs);
- weekCalendar = new WeekCalendar(context, attrs);
-
- monthCalendar.setId(R.id.N_monthCalendar);
- weekCalendar.setId(R.id.N_weekCalendar);
-
- setCalendarPainter(new InnerPainter(getContext(), this));
-
- OnMWDateChangeListener onMWDateChangeListener = (baseCalendar, localDate, totalCheckedDateList) -> {
- int childViewY = (int) childView.getY();
- if (baseCalendar == monthCalendar && (childViewY == monthHeight || childViewY == stretchMonthHeight)) {
- //交换数据,保证月周选中数据同步
- weekCalendar.exchangeCheckedDateList(totalCheckedDateList);
- //月日历变化,改变周的选中
- weekCalendar.jump(localDate, getCheckModel() == CheckModel.SINGLE_DEFAULT_CHECKED, DateChangeBehavior.API);
-
- } else if (baseCalendar == weekCalendar && childViewY == weekHeight) {
- //交换数据,保证月周选中数据同步
- monthCalendar.exchangeCheckedDateList(totalCheckedDateList);
- //周日历变化,改变月的选中
- monthCalendar.jump(localDate, getCheckModel() == CheckModel.SINGLE_DEFAULT_CHECKED, DateChangeBehavior.API);
- monthCalendar.post(() -> {
- //此时需要根据月日历的选中日期调整值
- // 跳转翻页需要时间,需要等待完成之后再调整,如果不这样直接获取位置信息,会出现老的数据,不能获取正确的数据
- monthCalendar.setY(getMonthYOnWeekState(localDate));
- });
- }
- };
- monthCalendar.setOnMWDateChangeListener(onMWDateChangeListener);
- weekCalendar.setOnMWDateChangeListener(onMWDateChangeListener);
-
- //背景颜色
- CalendarBackground monthBackground;
- if (this.attrs.showNumberBackground) {
- monthBackground = new NumBackground(this.attrs.numberBackgroundTextSize, this.attrs.numberBackgroundTextColor, this.attrs.numberBackgroundAlphaColor);
- } else if (this.attrs.calendarBackground != null) {
- monthBackground = (localDate, currentDistance, totalDistance) -> this.attrs.calendarBackground;
- } else {
- monthBackground = new WhiteBackground();
- }
-
- setMonthCalendarBackground(monthBackground);
- setWeekCalendarBackground(new WhiteBackground());
-
-
- addView(monthCalendar, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, monthHeight));
- addView(weekCalendar, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, weekHeight));
-
- monthValueAnimator = getValueAnimator(duration);
- monthStretchValueAnimator = getValueAnimator(duration);
-
- childViewValueAnimator = getValueAnimator(duration);
- OnEndAnimatorListener onEndAnimatorListener = new OnEndAnimatorListener() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- callBackCalendarState();
- }
- };
- childViewValueAnimator.addListener(onEndAnimatorListener);
-
- post(new Runnable() {
- @Override
- public void run() {
- monthCalendar.setVisibility(calendarState == CalendarState.MONTH ? VISIBLE : INVISIBLE);
- weekCalendar.setVisibility(calendarState == CalendarState.WEEK ? VISIBLE : INVISIBLE);
- monthRect = new RectF(0, 0, monthCalendar.getMeasuredWidth(), monthCalendar.getMeasuredHeight());
- weekRect = new RectF(0, 0, weekCalendar.getMeasuredWidth(), weekCalendar.getMeasuredHeight());
- stretchMonthRect = new RectF(0, 0, monthCalendar.getMeasuredWidth(), stretchMonthHeight);
- monthCalendar.setY(calendarState == CalendarState.MONTH ? 0 : getMonthYOnWeekState(weekCalendar.getFirstDate()));
- childView.setY(calendarState == CalendarState.MONTH ? monthHeight : weekHeight);
- isInflateFinish = true;
- }
- });
- }
-
- private ValueAnimator getValueAnimator(int duration) {
- ValueAnimator valueAnimator = new ValueAnimator();
- valueAnimator.setDuration(duration);
- valueAnimator.addUpdateListener(this);
- return valueAnimator;
- }
-
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- if (getChildCount() != 3) {
- throw new RuntimeException(getContext().getString(R.string.N_NCalendar_child_num));
- }
-
- for (int i = 0; i < getChildCount(); i++) {
- if (getChildAt(i) != monthCalendar && getChildAt(i) != weekCalendar) {
- childView = getChildAt(i);
- Drawable background = childView.getBackground();
- if (background == null) {
- childView.setBackgroundColor(Color.WHITE);
- }
- }
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- ViewGroup.LayoutParams childLayoutLayoutParams = childView.getLayoutParams();
- childLayoutLayoutParams.height = getMeasuredHeight() - weekHeight;
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- //super.onLayout(changed, l, t, r, b); //调用父类的该方法会造成 快速滑动月日历同时快速上滑recyclerview造成月日历的残影
-
- int measuredWidth = getMeasuredWidth();
- int paddingLeft = getPaddingLeft();
- int paddingRight = getPaddingRight();
-
- weekCalendar.layout(paddingLeft, 0, measuredWidth - paddingRight, weekHeight);
-
- if (childView.getY() >= monthHeight && isStretchCalendarEnable) {
- monthCalendar.layout(paddingLeft, 0, measuredWidth - paddingRight, stretchMonthHeight);
- } else {
- monthCalendar.layout(paddingLeft, 0, measuredWidth - paddingRight, monthHeight);
- }
- childView.layout(paddingLeft, monthHeight, measuredWidth - paddingRight, childView.getMeasuredHeight() + monthHeight);
-
-
- }
-
-
- //自动滑动到适当的位置
- private void autoScroll() {
- int childLayoutY = (int) childView.getY();
-
- if ((calendarState == CalendarState.MONTH || calendarState == CalendarState.MONTH_STRETCH) && childLayoutY <= monthHeight && childLayoutY >= monthHeight * 4 / 5) {
- autoToMonthBySetY();
- } else if ((calendarState == CalendarState.MONTH || calendarState == CalendarState.MONTH_STRETCH) && childLayoutY <= monthHeight * 4 / 5) {
- autoToWeekBySetY();
- } else if ((calendarState == CalendarState.WEEK || calendarState == CalendarState.MONTH_STRETCH) && childLayoutY < weekHeight * 2) {
- autoToWeekBySetY();
- } else if ((calendarState == CalendarState.WEEK || calendarState == CalendarState.MONTH_STRETCH) && childLayoutY >= weekHeight * 2 && childLayoutY <= monthHeight) {
- autoToMonthBySetY();
- } else if (childLayoutY < monthHeight + (stretchMonthHeight - monthHeight) / 2 && childLayoutY >= monthHeight) {
- autoToMonthFromStretch();
- } else if (childLayoutY >= monthHeight + (stretchMonthHeight - monthHeight) / 2) {
- autoToStretchFromMonth();
- }
- }
-
- //自动从拉伸到月状态 通过改变高度
- private void autoToMonthFromStretch() {
- float monthCalendarStart = monthCalendar.getLayoutParams().height;
- float monthCalendarEnd = monthHeight;
- monthStretchValueAnimator.setFloatValues(monthCalendarStart, monthCalendarEnd);
- monthStretchValueAnimator.start();
-
- float childViewStart = childView.getY();
- float childViewEnd = monthHeight;
- childViewValueAnimator.setFloatValues(childViewStart, childViewEnd);
- childViewValueAnimator.start();
- }
-
- //自动从月到拉伸状态 通过改变高度
- private void autoToStretchFromMonth() {
- float monthCalendarStart = monthCalendar.getLayoutParams().height;
- float monthCalendarEnd = stretchMonthHeight;
- monthStretchValueAnimator.setFloatValues(monthCalendarStart, monthCalendarEnd);
- monthStretchValueAnimator.start();
-
- float childViewStart = childView.getY();
- float childViewEnd = stretchMonthHeight;
- childViewValueAnimator.setFloatValues(childViewStart, childViewEnd);
- childViewValueAnimator.start();
-
- }
-
-
- //自动滑动到周 通过setY 月->周
- private void autoToWeekBySetY() {
- float monthCalendarStart = monthCalendar.getY();//起始位置
- float monthCalendarEnd = getMonthCalendarAutoWeekEndY();
-
- monthValueAnimator.setFloatValues(monthCalendarStart, monthCalendarEnd);
- monthValueAnimator.start();
-
- float childViewStart = childView.getY();
- float childViewEnd = weekHeight;
- childViewValueAnimator.setFloatValues(childViewStart, childViewEnd);
- childViewValueAnimator.start();
-
- }
-
- //自动滑动到月 通过setY 周->月
- private void autoToMonthBySetY() {
- float monthCalendarStart = monthCalendar.getY();
- float monthCalendarEnd = 0;
- monthValueAnimator.setFloatValues(monthCalendarStart, monthCalendarEnd);
- monthValueAnimator.start();
-
- float childViewStart = childView.getY();
- float childViewEnd = monthHeight;
- childViewValueAnimator.setFloatValues(childViewStart, childViewEnd);
- childViewValueAnimator.start();
- }
-
- @Override
- public boolean onStartNestedScroll(@NonNull View child, @NonNull View target, int nestedScrollAxes) {
- return true;
- }
-
- @Override
- public void onNestedScrollAccepted(@NonNull View child, @NonNull View target, int axes) {
- //super.onNestedScrollAccepted(child, target, axes);
- }
-
- @Override
- public void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
- // super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
- }
-
- @Override
- public boolean onNestedFling(@NonNull View target, float velocityX, float velocityY, boolean consumed) {
- return false;
- }
-
- @Override
- public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed) {
- //跟随手势滑动
- gestureMove(dy, consumed);
- }
-
- @Override
- public boolean onNestedPreFling(@NonNull View target, float velocityX, float velocityY) {
- return childView.getY() != weekHeight;
- }
-
- @Override
- public void onStopNestedScroll(@NonNull View target) {
-
- //该方法 在 View 类中11758行 actionMasked == MotionEvent.ACTION_DOWN down的时候会执行
- //此时 childViewY 必为 3个标志位之一,判断不为这三个数值就自动滑动
-
- int childViewY = (int) childView.getY();
-
- if (childViewY != monthHeight && childViewY != weekHeight && childViewY != stretchMonthHeight) {
- autoScroll();
- } else {
- callBackCalendarState();
- }
- }
-
- /**
- * 手势滑动的逻辑,
- * 1、起始位置 根据滑动的方向判断是月周切换还是月、拉伸切换
- * 2、起始条件触发后,根据childView的位置执行不同的逻辑 setY 和 拉伸高度
- */
- protected void gestureMove(float dy, int[] consumed) {
- float monthCalendarY = monthCalendar.getY();
- float childViewY = childView.getY();
-
- ViewGroup.LayoutParams layoutParams = monthCalendar.getLayoutParams();
- int realMonthHeight = layoutParams.height;
-
- if (dy > 0 && childViewY == monthHeight && monthCalendarY == 0) {
- //setY 起始位置 月->周的过程
- if (isStretchCalendarEnable && realMonthHeight != monthHeight) {
- layoutParams.height = monthHeight;
- monthCalendar.setLayoutParams(layoutParams);
- }
-
- monthCalendar.setY(-getGestureMonthUpOffset(dy) + monthCalendarY);
- childView.setY(-getGestureChildUpOffset(dy) + childViewY);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
-
- } else if (dy < 0 && childViewY == monthHeight && monthCalendarY == 0 && isStretchCalendarEnable) {
- //拉伸 起始位置 月->拉伸的过程
- float monthOffset = getOffset(-dy, stretchMonthHeight - realMonthHeight);
- layoutParams.height = (int) (layoutParams.height + monthOffset);
- monthCalendar.setLayoutParams(layoutParams);
-
- float childOffset = getOffset(-dy, stretchMonthHeight - childViewY);
- childView.setY(childViewY + childOffset);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
-
- } else if (dy > 0 && childViewY <= monthHeight && childViewY != weekHeight) {
- //setY 持续过程 月->周的过程
- if (isStretchCalendarEnable && realMonthHeight != monthHeight) {
- //由于滑动过程中可能存在从拉伸状态直接滑到周的状态,引起monthCalendar的高度还没有到monthHeight就向上滑动,所以在这里判断一下,高度正常之后才上滑
- layoutParams.height = monthHeight;
- monthCalendar.setLayoutParams(layoutParams);
- }
-
- monthCalendar.setY(-getGestureMonthUpOffset(dy) + monthCalendarY);
- childView.setY(-getGestureChildUpOffset(dy) + childViewY);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
-
- } else if (dy < 0 && childViewY <= monthHeight && childViewY >= weekHeight && (!(isWeekHoldEnable && calendarState == CalendarState.WEEK) || consumed == null) && (targetView == null || !targetView.canScrollVertically(-1))) {
- //setY 持续过程 周->月的过程
- if (isStretchCalendarEnable && realMonthHeight != monthHeight) {
- layoutParams.height = monthHeight;
- monthCalendar.setLayoutParams(layoutParams);
- }
-
- monthCalendar.setY(getGestureMonthDownOffset(dy) + monthCalendarY);
- childView.setY(getGestureChildDownOffset(dy) + childViewY);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
-
- } else if (dy < 0 && childViewY >= monthHeight && childViewY <= stretchMonthHeight && monthCalendarY == 0 && isStretchCalendarEnable) {
- //拉伸 持续过程 月->拉伸的过程
- float monthOffset = getOffset(-dy, stretchMonthHeight - realMonthHeight);
- layoutParams.height = (int) (layoutParams.height + monthOffset);
- monthCalendar.setLayoutParams(layoutParams);
-
- float childOffset = getOffset(-dy, stretchMonthHeight - childViewY);
- childView.setY(childViewY + childOffset);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
-
- } else if (dy > 0 && childViewY >= monthHeight && childViewY <= stretchMonthHeight && monthCalendarY == 0 && isStretchCalendarEnable) {
- //拉伸 持续过程 拉伸->月的过程
- float monthOffset = getOffset(-dy, stretchMonthHeight - realMonthHeight);
- layoutParams.height = (int) (layoutParams.height + monthOffset);
- monthCalendar.setLayoutParams(layoutParams);
-
- float childOffset = getOffset(-dy, stretchMonthHeight - childViewY);
- childView.setY(childViewY + childOffset);
-
- if (consumed != null) {
- consumed[1] = (int) dy;
- }
- scrolling(dy);
- }
-
- }
-
-
- private float downY;
- private float downX;
- //上次的y
- private float lastY;
- //竖直方向上滑动的临界值,大于这个值认为是竖直滑动
- private final float verticalY = 50.f;
- //第一次手势滑动,因为第一次滑动的偏移量大于verticalY,会出现猛的一划,这里只对第一次滑动做处理
- private boolean isFirstScroll = true;
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!isInflateFinish) {
- return super.onInterceptTouchEvent(ev);
- }
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- downY = ev.getY();
- downX = ev.getX();
- lastY = downY;
- targetView = ViewUtil.getTargetView(getContext(), childView);
- break;
- case MotionEvent.ACTION_MOVE:
- float y = ev.getY();
- float absY = Math.abs(downY - y);
- boolean inCalendar = isInCalendar(downX, downY);
- if ((absY > verticalY && inCalendar) || targetView == null && absY > verticalY) {
- //onInterceptTouchEvent返回true,触摸事件交给当前的onTouchEvent处理
- return true;
- }
- break;
-
- }
- return super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_MOVE:
- float y = event.getY();
- float dy = lastY - y;
- if (isFirstScroll) {
- // 防止第一次的偏移量过大
- if (dy > verticalY) {
- dy = dy - verticalY;
- } else if (dy < -verticalY) {
- dy = dy + verticalY;
- }
- isFirstScroll = false;
- }
- // 跟随手势滑动
- gestureMove(dy, null);
- lastY = y;
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- isFirstScroll = true;
- autoScroll();
- break;
- }
- return true;
- }
-
-
- //点击事件是否在日历的范围内
- private boolean isInCalendar(float x, float y) {
- if (calendarState == CalendarState.MONTH) {
- return monthRect.contains(x, y);
- } else if (calendarState == CalendarState.WEEK) {
- return weekRect.contains(x, y);
- } else if (calendarState == CalendarState.MONTH_STRETCH) {
- return stretchMonthRect.contains(x, y);
- }
- return false;
- }
-
-
- @Override
- public void jumpDate(String formatDate) {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.jumpDate(formatDate);
- } else {
- monthCalendar.jumpDate(formatDate);
- }
- }
-
- @Override
- public void jumpDate(int year, int month, int day) {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.jumpDate(year, month, day);
- } else {
- monthCalendar.jumpDate(year, month, day);
- }
- }
-
- @Override
- public void jumpMonth(int year, int month) {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.jumpMonth(year, month);
- } else {
- monthCalendar.jumpMonth(year, month);
- }
- }
-
- @Override
- public void setInitializeDate(String formatDate) {
- monthCalendar.setInitializeDate(formatDate);
- weekCalendar.setInitializeDate(formatDate);
- }
-
- @Override
- public void setCheckedDates(List dateList) {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.setCheckedDates(dateList);
- } else {
- monthCalendar.setCheckedDates(dateList);
- }
- }
-
- @Override
- public void toToday() {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.toToday();
- } else {
- monthCalendar.toToday();
- }
- }
-
- @Override
- public void toWeek() {
- if (calendarState == CalendarState.MONTH) {
- autoToWeekBySetY();
- }
- }
-
- @Override
- public void toMonth() {
- if (calendarState == CalendarState.WEEK) {
- autoToMonthBySetY();
- } else if (calendarState == CalendarState.MONTH_STRETCH) {
- autoToMonthFromStretch();
- }
- }
-
- @Override
- public void toStretch() {
- if (calendarState == CalendarState.MONTH) {
- autoToStretchFromMonth();
- }
- }
-
- @Override
- public CalendarPainter getCalendarPainter() {
- return monthCalendar.getCalendarPainter();
- }
-
- @Override
- public CalendarAdapter getCalendarAdapter() {
- return monthCalendar.getCalendarAdapter();
- }
-
- @Override
- public CalendarState getCalendarState() {
- return calendarState;
- }
-
- @Override
- public void setCalendarState(CalendarState calendarState) {
- if (calendarState == CalendarState.MONTH_STRETCH) {
- throw new RuntimeException(getContext().getString(R.string.N_calendarState_illegal));
- }
- this.calendarState = calendarState;
- }
-
- @Override
- public void toNextPager() {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.toNextPager();
- } else {
- monthCalendar.toNextPager();
- }
- }
-
- @Override
- public void toLastPager() {
- if (calendarState == CalendarState.WEEK) {
- weekCalendar.toLastPager();
- } else {
- monthCalendar.toLastPager();
- }
- }
-
- @Override
- public void setCheckMode(CheckModel checkModel) {
- monthCalendar.setCheckMode(checkModel);
- weekCalendar.setCheckMode(checkModel);
- }
-
- @Override
- public CheckModel getCheckModel() {
- return monthCalendar.getCheckModel();
- }
-
-
- @Override
- public void setDefaultCheckedFirstDate(boolean isDefaultSelectFitst) {
- monthCalendar.setDefaultCheckedFirstDate(isDefaultSelectFitst);
- weekCalendar.setDefaultCheckedFirstDate(isDefaultSelectFitst);
- }
-
- @Override
- public void setDateInterval(String startFormatDate, String endFormatDate) {
- monthCalendar.setDateInterval(startFormatDate, endFormatDate);
- weekCalendar.setDateInterval(startFormatDate, endFormatDate);
- }
-
- @Override
- public void setOnCalendarChangedListener(OnCalendarChangedListener onCalendarChangedListener) {
- monthCalendar.setOnCalendarChangedListener(onCalendarChangedListener);
- weekCalendar.setOnCalendarChangedListener(onCalendarChangedListener);
- }
-
-
- @Override
- public void setOnCalendarMultipleChangedListener(OnCalendarMultipleChangedListener onCalendarMultipleChangedListener) {
- monthCalendar.setOnCalendarMultipleChangedListener(onCalendarMultipleChangedListener);
- weekCalendar.setOnCalendarMultipleChangedListener(onCalendarMultipleChangedListener);
- }
-
- @Override
- public void updateSlideDistance(int currentDistance) {
- monthCalendar.updateSlideDistance(currentDistance - weekHeight);
- weekCalendar.updateSlideDistance(currentDistance - weekHeight);
- }
-
- @Override
- public void setOnCalendarStateChangedListener(OnCalendarStateChangedListener onCalendarStateChangedListener) {
- this.onCalendarStateChangedListener = onCalendarStateChangedListener;
- }
-
- @Override
- public void setOnCalendarScrollingListener(OnCalendarScrollingListener onCalendarScrollingListener) {
- this.onCalendarScrollingListener = onCalendarScrollingListener;
- }
-
- @Override
- public void setOnClickDisableDateListener(OnClickDisableDateListener onClickDisableDateListener) {
- monthCalendar.setOnClickDisableDateListener(onClickDisableDateListener);
- weekCalendar.setOnClickDisableDateListener(onClickDisableDateListener);
- }
-
- @Override
- public void setCalendarPainter(CalendarPainter calendarPainter) {
- monthCalendar.setCalendarPainter(calendarPainter);
- weekCalendar.setCalendarPainter(calendarPainter);
- }
-
- @Override
- public void notifyCalendar() {
- monthCalendar.notifyCalendar();
- weekCalendar.notifyCalendar();
- }
-
- @Override
- public void setDateInterval(String startFormatDate, String endFormatDate, String formatInitializeDate) {
- monthCalendar.setDateInterval(startFormatDate, endFormatDate, formatInitializeDate);
- weekCalendar.setDateInterval(startFormatDate, endFormatDate, formatInitializeDate);
- }
-
- @Override
- public void setMultipleCount(int multipleCount, MultipleCountModel multipleCountModel) {
- monthCalendar.setMultipleCount(multipleCount, multipleCountModel);
- weekCalendar.setMultipleCount(multipleCount, multipleCountModel);
- }
-
- @Override
- public void setLastNextMonthClickEnable(boolean enable) {
- monthCalendar.setLastNextMonthClickEnable(enable);
- weekCalendar.setLastNextMonthClickEnable(enable);
- }
-
- @Override
- public Attrs getAttrs() {
- return attrs;
- }
-
-
- @Override
- public void setCalendarAdapter(CalendarAdapter calendarAdapter) {
- monthCalendar.setCalendarAdapter(calendarAdapter);
- weekCalendar.setCalendarAdapter(calendarAdapter);
- }
-
- @Override
- public List getTotalCheckedDateList() {
- if (calendarState == CalendarState.WEEK) {
- return weekCalendar.getTotalCheckedDateList();
- } else {
- return monthCalendar.getTotalCheckedDateList();
- }
- }
-
- @Override
- public List getCurrPagerCheckDateList() {
- if (calendarState == CalendarState.WEEK) {
- return weekCalendar.getCurrPagerCheckDateList();
- } else {
- return monthCalendar.getCurrPagerCheckDateList();
- }
- }
-
- @Override
- public List getCurrPagerDateList() {
- if (calendarState == CalendarState.WEEK) {
- return weekCalendar.getCurrPagerDateList();
- } else {
- return monthCalendar.getCurrPagerDateList();
- }
- }
-
- @Override
- public void setWeekHoldEnable(boolean isWeekHoldEnable) {
- this.isWeekHoldEnable = isWeekHoldEnable;
- }
-
- @Override
- public void setStretchCalendarEnable(boolean isMonthStretchEnable) {
- this.isStretchCalendarEnable = isMonthStretchEnable;
- }
-
- @Override
- public void setScrollEnable(boolean scrollEnable) {
- monthCalendar.setScrollEnable(scrollEnable);
- weekCalendar.setScrollEnable(scrollEnable);
- }
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
-
- if (animation == monthValueAnimator) {
- float animatedValue = (float) animation.getAnimatedValue();
- monthCalendar.setY(animatedValue);
- } else if (animation == monthStretchValueAnimator) {
- float animatedValue = (float) animation.getAnimatedValue();
- ViewGroup.LayoutParams layoutParams = monthCalendar.getLayoutParams();
- layoutParams.height = (int) animatedValue;
- monthCalendar.setLayoutParams(layoutParams);
- } else if (animation == childViewValueAnimator) {
- float animatedValue = (float) animation.getAnimatedValue();
- float top = childView.getY();
- float i = animatedValue - top;
- childView.setY(animatedValue);
-
- scrolling((int) -i);
-
- }
- }
-
- //设置日历的状态、月周的显示及状态回调
- private void callBackCalendarState() {
-
- int childViewY = (int) childView.getY();
-
- if (childViewY == weekHeight && calendarState != CalendarState.WEEK) {
- calendarState = CalendarState.WEEK;
- weekCalendar.setVisibility(VISIBLE);
- monthCalendar.setVisibility(INVISIBLE);
- if (onCalendarStateChangedListener != null) {
- onCalendarStateChangedListener.onCalendarStateChange(calendarState);
- }
-
- } else if (childViewY == monthHeight && calendarState != CalendarState.MONTH) {
- calendarState = CalendarState.MONTH;
- weekCalendar.setVisibility(INVISIBLE);
- monthCalendar.setVisibility(VISIBLE);
-
- //重新设置周的显示 展开月日历上面可能有选中的日期,需要下次折叠时周日历的显示要正确
- LocalDate pivot = monthCalendar.getPivotDate();
- weekCalendar.jump(pivot, getCheckModel() == CheckModel.SINGLE_DEFAULT_CHECKED, DateChangeBehavior.API);
-
- if (onCalendarStateChangedListener != null) {
- onCalendarStateChangedListener.onCalendarStateChange(calendarState);
- }
- } else if (childViewY == stretchMonthHeight && calendarState != CalendarState.MONTH_STRETCH) {
- calendarState = CalendarState.MONTH_STRETCH;
- weekCalendar.setVisibility(INVISIBLE);
- monthCalendar.setVisibility(VISIBLE);
-
- //重新设置周的显示 展开月日历上面可能有选中的日期,需要下次折叠时周日历的显示要正确
- LocalDate pivot = monthCalendar.getPivotDate();
- weekCalendar.jump(pivot, getCheckModel() == CheckModel.SINGLE_DEFAULT_CHECKED, DateChangeBehavior.API);
-
- if (onCalendarStateChangedListener != null) {
- onCalendarStateChangedListener.onCalendarStateChange(calendarState);
- }
- }
-
- }
-
- //childView周状态的条件 容错状态
- protected boolean isChildWeekState() {
- return childView.getY() <= weekHeight;
- }
-
- //月日历周状态 容错状态
- protected boolean isMonthCalendarWeekState() {
- return monthCalendar.getY() <= -monthCalendar.getPivotDistanceFromTop();
- }
-
- //滑动中 包含跟随手势和自动滑动
- protected void scrolling(float dy) {
- setWeekVisible(dy > 0);
- updateSlideDistance((int) childView.getY());
- if (onCalendarScrollingListener != null) {
- onCalendarScrollingListener.onCalendarScrolling(dy);
- }
- }
-
-
- //获取月日历自动到周状态的y值
- protected abstract float getMonthCalendarAutoWeekEndY();
-
- //周状态下 月日历的getY 是个负值,用于在 周状态下日期改变设置正确的y值
- protected abstract float getMonthYOnWeekState(LocalDate localDate);
-
- //滑动过界处理 ,如果大于最大距离就返回最大距离
- protected float getOffset(float offset, float maxOffset) {
- return Math.min(offset, maxOffset);
- }
-
- /**
- * 设置weekCalendar的显示隐藏,该方法会在手势滑动和自动滑动的的时候一直回调
- * isUp 是否是向上滑动
- */
- protected abstract void setWeekVisible(boolean isUp);
-
- /**
- * 月日历根据手势向上移动的距离
- *
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- * @return 根据不同日历的交互,计算不同的滑动值
- */
- protected abstract float getGestureMonthUpOffset(float dy);
-
- /**
- * Child根据手势向上移动的距离
- *
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- * @return 根据不同日历的交互,计算不同的滑动值
- */
- protected abstract float getGestureChildUpOffset(float dy);
-
- /**
- * 月日历根据手势向下移动的距离
- *
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- * @return 根据不同日历的交互,计算不同的滑动值
- */
- protected abstract float getGestureMonthDownOffset(float dy);
-
- /**
- * Child根据手势向下移动的距离
- *
- * @param dy 当前滑动的距离 dy>0向上滑动,dy<0向下滑动
- * @return 根据不同日历的交互,计算不同的滑动值
- */
- protected abstract float getGestureChildDownOffset(float dy);
-
-
- @Override
- public CalendarBackground getCalendarBackground() throws IllegalAccessException {
- throw new IllegalAccessException(getContext().getString(R.string.N_NCalendar_calendar_background_illegal));
- }
-
- @Override
- public void setCalendarBackground(CalendarBackground calendarBackground) throws IllegalAccessException {
- throw new IllegalAccessException(getContext().getString(R.string.N_NCalendar_set_calendar_background_illegal));
- }
-
- @Override
- public void setMonthCalendarBackground(CalendarBackground calendarBackground) {
- monthCalendar.setCalendarBackground(calendarBackground);
- }
-
- @Override
- public void setWeekCalendarBackground(CalendarBackground calendarBackground) {
- weekCalendar.setCalendarBackground(calendarBackground);
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/calendar/NCalendar.kt b/ncalendar/src/main/java/com/necer/calendar/NCalendar.kt
new file mode 100644
index 00000000..2d16da78
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/calendar/NCalendar.kt
@@ -0,0 +1,609 @@
+package com.necer.calendar
+
+import android.animation.Animator
+import android.animation.ValueAnimator
+import android.content.Context
+import android.graphics.Color
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import androidx.core.view.NestedScrollingParent
+import com.necer.R
+import com.necer.enumeration.CalendarState
+import com.necer.enumeration.CheckModel
+import com.necer.enumeration.MultipleCountModel
+import com.necer.listener.*
+import com.necer.painter.CalendarPainter
+import com.necer.utils.NAttrs
+import com.necer.utils.NAttrsUtil
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+/**
+ * 日历
+ * 1、NCalendar中包含子View时,日历为月周切换日历
+ * 2、NCalendar中包含子View时,日历为单个日历,单独使用,是周日历还是月日历由 defaultCalendar 的值决定
+ */
+class NCalendar(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs), ICalendar,
+ NestedScrollingParent {
+
+
+ private var nWeekBar: NWeekBar
+ private var nViewPager: NViewPager
+
+ private var monthHeight = 0
+ private var stretchHeight = 0
+ private var weekHeight = 0
+
+ private var monthStateY = 0
+ private var weekStateY = 0
+ private var stretchStateY = 0
+
+
+ private var valueAnimator: ValueAnimator = ValueAnimator()
+
+ private var previousValue = 0f//松手动画开始之后 用于计算动画的增量
+
+ private var childView: FrameLayout//NCalendar内部包含的直接子view,直接子view并不一定是NestScrillChild
+ private var targetView: View? = null //实际滑动的view 当targetView==null时,子view没有NestScrillChild,此时滑动交给onTochEvent处理
+
+ private var isLayout: Boolean = false
+
+ private var lastCalendarState: CalendarState? = null
+
+ private var onCalendarStateChangedListener: OnCalendarStateChangedListener? = null
+
+ private var isWeekHoldEnable: Boolean = false
+
+
+ init {
+
+ orientation = VERTICAL
+ isMotionEventSplittingEnabled = false
+
+ //自定义属性赋值
+ NAttrsUtil.setAttrs(context, attrs)
+
+ monthHeight = NAttrs.calendarHeight
+ weekHeight = monthHeight / 5
+ stretchHeight = NAttrs.stretchCalendarHeight
+
+ if (stretchHeight <= monthHeight) {
+ throw RuntimeException("拉伸状态的高度必须大于月日历高度")
+ }
+
+ nWeekBar = NWeekBar(context, null)
+ nViewPager = NViewPager(context, null)
+ addView(
+ nWeekBar,
+ LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ if (NAttrs.weekBarHeight == 0) LayoutParams.WRAP_CONTENT else NAttrs.weekBarHeight
+ )
+ )
+ addView(nViewPager, LayoutParams(LayoutParams.MATCH_PARENT, stretchHeight))
+ childView = FrameLayout(context)
+ childView.isClickable = true
+ childView.setBackgroundColor(Color.WHITE)
+ addView(childView, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
+
+ }
+
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+ if (childCount > 4) {
+ throw RuntimeException(context.getString(R.string.N_NCalendar_child_num))
+ }
+ if (childCount == 4) {
+ val view = getChildAt(3)
+ (view.parent as ViewGroup).removeView(view)
+ childView.addView(
+ view,
+ LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
+ )
+ }
+
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ if (!isLayout) {
+ if (childView.childCount != 0) {
+ val childLayoutParams = childView.layoutParams
+ childLayoutParams.height = measuredHeight - weekHeight - nWeekBar.measuredHeight
+
+ monthStateY = nWeekBar.measuredHeight + monthHeight
+ weekStateY = nWeekBar.measuredHeight + weekHeight
+ stretchStateY = nWeekBar.measuredHeight + stretchHeight
+
+ } else {
+
+ val height = when (getCalendarState()) {
+ CalendarState.WEEK -> weekHeight
+ CalendarState.MONTH -> monthHeight
+ CalendarState.MONTH_STRETCH -> stretchHeight
+ else -> 0
+ }
+
+ //日历中没有子view
+ val viewPagerLayoutParams = nViewPager.layoutParams
+ viewPagerLayoutParams.height = height
+
+ //计算NCalendar的高度
+ layoutParams.height = height + nWeekBar.measuredHeight
+ }
+ }
+ }
+
+ override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
+ super.onLayout(changed, l, t, r, b)
+ if (!isLayout) {
+ val childY = when (getCalendarState()) {
+ CalendarState.WEEK -> weekStateY
+ CalendarState.MONTH -> monthStateY
+ CalendarState.MONTH_STRETCH -> stretchStateY
+ else -> 0
+ }
+ childView.y = childY.toFloat()
+ isLayout = true
+ }
+ }
+
+
+ private var downY = 0f
+ private var downX = 0f
+
+ //上次的y
+ private var lastY = 0f
+
+ //竖直方向上滑动的临界值,大于这个值认为是竖直滑动
+ private val verticalY = 30f
+
+ private var directionY = 0 // 1 竖直向上 -1 竖直向下
+ private var isFirstMove = true
+
+
+ override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
+
+
+ if (childView.childCount == 0) {
+ return super.onInterceptTouchEvent(ev)
+ }
+
+ if (valueAnimator.isRunning) {
+ valueAnimator.cancel()
+ }
+
+ when (ev.action) {
+ MotionEvent.ACTION_DOWN -> {
+ downY = ev.y
+ downX = ev.x
+ lastY = downY
+ }
+ MotionEvent.ACTION_MOVE -> {
+ //中间状态
+ if (nViewPager.getCalendarState() == null) {
+ return true
+ }
+
+ val y = ev.y
+ val offsetY = downY - y
+
+ //onInterceptTouchEvent返回true,触摸事件交给当前的onTouchEvent处理
+ return interceptTouch(offsetY)
+
+ }
+ MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
+ if (downY > weekStateY && downY < childView.y) {
+ isFirstMove = true
+ autoScroll(NAttrs.animationDuration.toLong())
+ }
+
+ }
+
+ }
+ return super.onInterceptTouchEvent(ev)
+ }
+
+ private fun interceptTouch(offsetY: Float): Boolean {
+
+
+ val absY = Math.abs(offsetY)
+ var condition = false
+
+ if (targetView == null) {
+ condition = true
+ } else if (isInCalendar() && !targetView!!.canScrollVertically(-1)) {
+ condition = true
+ }
+ return condition && absY > verticalY
+ }
+
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+
+ when (event.action) {
+ MotionEvent.ACTION_MOVE -> {
+ val y = event.y
+ var dy = lastY - y
+ if (isFirstMove) {
+ // 防止第一次的偏移量过大
+ if (dy >= verticalY) {
+ dy -= verticalY
+ } else if (dy < -verticalY) {
+ dy += verticalY
+ }
+
+ isFirstMove = false
+ }
+ directionY = if (dy > 0) 1 else -1
+
+ if (Math.abs(dy) > 0) {
+ gestureMove(dy)
+ lastY = y
+ }
+
+ }
+ MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
+ isFirstMove = true
+ autoScroll(NAttrs.animationDuration.toLong())
+ }
+ }
+ return super.onTouchEvent(event)
+ }
+
+ private fun gestureMove(dy: Float) {
+
+ if (valueAnimator.isRunning) {
+ valueAnimator.cancel()
+ }
+
+ if (Math.round(childView.y) == weekStateY && isWeekHoldEnable) {
+ return
+ }
+
+ var childY = childView.y - dy
+ val maxY = if (NAttrs.stretchCalendarEnable) stretchStateY else monthStateY
+ if (childY <= weekStateY) {
+ childY = weekStateY.toFloat()
+ } else if (childY >= maxY) {
+ childY = maxY.toFloat()
+ }
+
+ childView.y = childY
+ calendarTranslate(dy)
+
+ val preCalendarState = getPreCalendarState(childView.y)
+ if (preCalendarState != null) {
+ nViewPager.setCalendarState(preCalendarState)
+ }
+
+
+ }
+
+ private fun calendarTranslate(dy: Float) {
+ if (Math.round(dy) == 0) {
+ return
+ }
+ val holdHeight = nViewPager.getHoldHeight()
+ val heightOffset = monthHeight - weekHeight
+ val translateRate = holdHeight / heightOffset
+ nViewPager.offsetView(dy * translateRate)
+ }
+
+
+ private fun isInCalendar(): Boolean {
+ val calendarState = nViewPager.getCalendarState()
+ if (calendarState === CalendarState.MONTH) {
+ return downY <= monthStateY
+ } else if (calendarState === CalendarState.WEEK) {
+ return downY <= weekStateY
+ } else if (calendarState === CalendarState.MONTH_STRETCH) {
+ return downY <= stretchStateY
+ }
+ return false
+ }
+
+
+ private fun autoScroll(duration: Long) {
+
+ if (valueAnimator.isRunning) {
+ return
+ }
+
+ val startY: Float = childView.y
+ val endY: Int
+
+ if (directionY == 1) {
+ //向上
+ endY = if (startY >= weekStateY && startY <= monthStateY) {
+ if (startY < monthStateY - weekHeight / 2) {
+ weekStateY
+ } else {
+ monthStateY
+ }
+ } else {
+ if (startY < stretchStateY - (stretchStateY - monthStateY) / 2) {
+ monthStateY
+ } else {
+ stretchStateY
+ }
+ }
+ } else {
+ //向下
+ endY = if (startY >= weekStateY && startY <= monthStateY) {
+ if (startY > weekStateY + weekHeight / 2) {
+ monthStateY
+ } else {
+ weekStateY
+ }
+ } else {
+ if (startY > monthStateY + (stretchStateY - monthStateY) / 2) {
+ stretchStateY
+ } else {
+ monthStateY
+ }
+ }
+ }
+
+ val preCalendarState = getPreCalendarState(endY.toFloat())
+
+ //位置不变 且 状态不变的时候 不执行动画
+ if (startY == endY.toFloat() && lastCalendarState == preCalendarState) {
+ return
+ }
+
+ startAutoScroll(startY, endY.toFloat(), duration)
+
+ }
+
+ private fun startAutoScroll(startY: Float, endY: Float, duration: Long) {
+
+ valueAnimator = ValueAnimator()
+ valueAnimator.duration = duration
+ valueAnimator.addUpdateListener { animation ->
+ val currentValue = animation.animatedValue as Float
+ if (previousValue != 0f) {
+ val delta = previousValue - currentValue
+ calendarTranslate(delta)
+ childView.y = childView.y - delta
+ }
+ previousValue = currentValue // 更新之前的值
+
+ }
+
+ valueAnimator.addListener(object : OnEndAnimatorListener() {
+ override fun onAnimationEnd(animation: Animator) {
+ super.onAnimationEnd(animation)
+ previousValue = 0f
+
+ val endCalendarState = getPreCalendarState(childView.y)
+
+ if (endCalendarState != null) {
+ nViewPager.setCalendarState(endCalendarState)
+ onCalendarStateChangedListener?.onCalendarStateChange(endCalendarState)
+ lastCalendarState = endCalendarState
+ }
+ }
+ })
+
+ valueAnimator.setFloatValues(startY, endY)
+ valueAnimator.start()
+ }
+
+
+ fun getCanvasHeight(): Float {
+ return if (childView.childCount == 0 || childView.y <= monthStateY) {
+ monthHeight.toFloat()
+ } else {
+ return childView.y - nWeekBar.measuredHeight
+ }
+ }
+
+ fun getChildY(): Float {
+ return childView.y
+ }
+
+ fun getMonthStateY(): Int {
+ return monthStateY
+ }
+
+ fun getWeekStateY(): Int {
+ return weekStateY
+ }
+
+ override fun getCalendarState(): CalendarState? {
+ return nViewPager.getCalendarState()
+ }
+
+ private fun getPreCalendarState(childY: Float): CalendarState? {
+ when (Math.round(childY)) {
+ weekStateY -> {
+ return CalendarState.WEEK
+ }
+ monthStateY -> {
+ return CalendarState.MONTH
+ }
+ stretchStateY -> {
+ return CalendarState.MONTH_STRETCH
+ }
+ }
+ return null
+ }
+
+ override fun onStartNestedScroll(child: View, target: View, nestedScrollAxes: Int): Boolean {
+ targetView = target
+
+ if (isWeekHoldEnable && calendarState === CalendarState.WEEK) {
+ return false
+ }
+ return true
+ }
+
+ override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray) {
+ super.onNestedPreScroll(target, dx, dy, consumed)
+
+ val childY = childView.y.toInt()
+
+ directionY = if (dy > 0) 1 else -1
+
+ if (childY > weekStateY && childY <= stretchStateY) {
+ consumed[1] = dy
+ gestureMove(dy.toFloat())
+ } else if (dy < 0 && !targetView!!.canScrollVertically(-1)) {
+ consumed[1] = dy
+ gestureMove(dy.toFloat())
+ }
+
+ }
+
+ override fun onNestedPreFling(target: View, velocityX: Float, velocityY: Float): Boolean {
+
+ //快速滑动时 快速自动滑动到对应的状态
+ if (velocityY > 6000) {
+ autoScroll(50)
+ } else if (velocityY < -6000) {
+ autoScroll(50)
+ }
+
+ //真正的快速滑动在周状态才行
+ return Math.round(childView.y) != weekStateY
+ }
+
+
+ override fun onStopNestedScroll(child: View) {
+ super.onStopNestedScroll(child)
+ targetView = null
+ autoScroll(NAttrs.animationDuration.toLong())
+ }
+
+ override fun toWeek() {
+ startAutoScroll(childView.y, weekStateY.toFloat(), NAttrs.animationDuration.toLong())
+ }
+
+ override fun toMonth() {
+ startAutoScroll(childView.y, monthStateY.toFloat(), NAttrs.animationDuration.toLong())
+ }
+
+ override fun toStretch() {
+ if (NAttrs.stretchCalendarEnable) {
+ startAutoScroll(childView.y, stretchStateY.toFloat(), NAttrs.animationDuration.toLong())
+ }
+ }
+
+ override fun setWeekHoldEnable(isWeekHoldEnable: Boolean) {
+ this.isWeekHoldEnable = isWeekHoldEnable
+ }
+
+
+ override fun setCheckMode(checkModel: CheckModel) {
+ nViewPager.setCheckMode(checkModel)
+ }
+
+ override fun getCheckModel(): CheckModel {
+ return nViewPager.getCheckMode()
+ }
+
+ override fun setMultipleCount(multipleCount: Int, multipleCountModel: MultipleCountModel?) {
+ nViewPager.setMultipleCount(multipleCount, multipleCountModel)
+ }
+
+
+ override fun jumpDate(formatDate: String?) {
+ val localDate = LocalDate.parse(formatDate, DateTimeFormatter.ofPattern("yyyy-M-d"))
+ nViewPager.jumpDate(localDate, true)
+ }
+
+ override fun jumpDate(year: Int, month: Int, day: Int) {
+ val localDate = LocalDate.of(year, month, day)
+ nViewPager.jumpDate(localDate, true)
+ }
+
+ override fun jumpMonth(year: Int, month: Int) {
+ val localDate = LocalDate.of(year, month, 1)
+ nViewPager.jumpDate(localDate, false)
+ }
+
+ override fun toLastPager() {
+ nViewPager.toLastPager()
+ }
+
+ override fun toNextPager() {
+ nViewPager.toNextPager()
+ }
+
+ override fun toToday() {
+ nViewPager.toToday()
+ }
+
+ override fun setCalendarPainter(calendarPainter: CalendarPainter?) {
+ nViewPager.setCalendarPainter(calendarPainter)
+ }
+
+ override fun notifyCalendar() {
+ nViewPager.notifyAllView()
+ }
+
+ override fun setInitializeDate(formatInitializeDate: String?) {
+ nViewPager.setInitializeDate(
+ LocalDate.parse(
+ formatInitializeDate,
+ DateTimeFormatter.ofPattern("yyyy-M-dd")
+ )
+ )
+ }
+
+ override fun setDateInterval(
+ startFormatDate: String?,
+ endFormatDate: String?,
+ formatInitializeDate: String?
+ ) {
+ nViewPager.setDateInterval(startFormatDate, endFormatDate, formatInitializeDate)
+ }
+
+ override fun setDateInterval(startFormatDate: String?, endFormatDate: String?) {
+ nViewPager.setDateInterval(startFormatDate, endFormatDate)
+ }
+
+ override fun setOnCalendarChangedListener(onCalendarChangedListener: OnCalendarChangedListener?) {
+ nViewPager.setOnCalendarChangedListener(onCalendarChangedListener)
+ }
+
+ override fun setOnCalendarMultipleChangedListener(onCalendarMultipleChangedListener: OnCalendarMultipleChangedListener?) {
+ nViewPager.setOnCalendarMultipleChangedListener(onCalendarMultipleChangedListener)
+ }
+
+ override fun setOnClickDisableDateListener(onClickDisableDateListener: OnClickDisableDateListener?) {
+ nViewPager.setOnClickDisableDateListener(onClickDisableDateListener)
+ }
+
+ override fun getCalendarPainter(): CalendarPainter {
+ return nViewPager.getCalendarPainter()
+ }
+
+ override fun getTotalCheckedDateList(): List {
+ return nViewPager.getTotalCheckedDateList()
+ }
+
+ override fun getCurrPagerCheckDateList(): List {
+ return nViewPager.getCurrPagerCheckedDateList()
+ }
+
+ override fun getCurrPagerDateList(): List {
+ return nViewPager.getCurrPagerDateList()
+ }
+
+ override fun setCheckedDates(dateList: List) {
+ nViewPager.setCheckedDates(dateList)
+ }
+
+ override fun setOnCalendarStateChangedListener(onCalendarStateChangedListener: OnCalendarStateChangedListener?) {
+ this.onCalendarStateChangedListener = onCalendarStateChangedListener
+ }
+
+
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/calendar/NCalendarView.kt b/ncalendar/src/main/java/com/necer/calendar/NCalendarView.kt
new file mode 100644
index 00000000..f68a0e0e
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/calendar/NCalendarView.kt
@@ -0,0 +1,321 @@
+package com.necer.calendar
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.view.GestureDetector
+import android.view.GestureDetector.SimpleOnGestureListener
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import com.necer.drawable.TextDrawable
+import com.necer.enumeration.CalendarState
+import com.necer.painter.CalendarPainter
+import com.necer.utils.NAttrs
+import com.necer.utils.NDateUtil
+import java.time.LocalDate
+
+class NCalendarView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
+
+ private lateinit var monthDateList: List
+ private var monthRectFList: List? = null
+
+ private lateinit var weekDateList: List
+ private var weekRectFList: List? = null
+
+ private var canvasOffset: Float = -1f
+
+ private lateinit var mGestureDetector: GestureDetector
+
+ lateinit var pagerInitDate: LocalDate
+
+ private lateinit var nViewPager: NViewPager
+
+ private lateinit var calendarPainter: CalendarPainter
+
+ private var backgroundRect: Rect = Rect()
+ private var monthStateY = 0
+ private var weekStateY = 0
+
+ private var bgDrawable: Drawable? = null
+
+
+ constructor(context: Context?) : this(context, null)
+
+
+ constructor(context: Context?, viewGroup: ViewGroup, localDate: LocalDate) : this(context, null) {
+ this.pagerInitDate = localDate
+ nViewPager = viewGroup as NViewPager
+
+ monthDateList = NDateUtil.getMonthDate(pagerInitDate, NAttrs.firstDayOfWeek, NAttrs.allMonthSixLine)
+ weekDateList = NDateUtil.getWeekDate(pagerInitDate, NAttrs.firstDayOfWeek)
+
+ calendarPainter = nViewPager.getCalendarPainter()
+
+ mGestureDetector = GestureDetector(context, object : SimpleOnGestureListener() {
+ override fun onDown(e: MotionEvent): Boolean {
+ return nViewPager.getCalendarState() != null
+ }
+
+ override fun onSingleTapUp(e: MotionEvent): Boolean {
+
+ val rectFList: List
+ val dateList: List
+ if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ rectFList = weekRectFList!!
+ dateList = weekDateList
+ } else {
+ rectFList = monthRectFList!!
+ dateList = monthDateList
+ }
+
+ for (i in rectFList.indices) {
+ val rectF = rectFList[i]
+ if (rectF.contains(e.x, e.y)) {
+ val clickDate = dateList[i]
+ nViewPager.setClickDate(clickDate)
+ break
+ }
+ }
+ return true
+ }
+ })
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+
+ if (monthStateY == 0) {
+ monthStateY = nViewPager.getMonthStateY()
+ weekStateY = nViewPager.getWeekStateY()
+ }
+
+ if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ drawWeekData(canvas)
+ } else {
+ canvas.translate(0f, -canvasOffset)
+ drawBgDrawable(canvas)
+ drawMonthDate(canvas)
+ }
+ }
+
+ private fun drawBgDrawable(canvas: Canvas) {
+ if (bgDrawable == null) {
+ bgDrawable = if (NAttrs.calendarBackground != null) {
+ NAttrs.calendarBackground
+ } else if (NAttrs.showNumberBackground) {
+ TextDrawable()
+ } else {
+ null
+ }
+ }
+
+ if (bgDrawable != null) {
+ val canvasHeight = nViewPager.getCanvasHeight()
+ backgroundRect.set(0, 0, width, canvasHeight.toInt())
+ val childY = nViewPager.getChildY()
+ var alpha = (childY - weekStateY) / (monthStateY - weekStateY)
+ if (alpha > 1) {
+ alpha = 1f
+ }
+
+ (bgDrawable as? TextDrawable)?.setText(nViewPager.fulcrumDate.monthValue.toString())
+ bgDrawable?.bounds = backgroundRect
+ bgDrawable?.alpha = (alpha * NAttrs.backgroundAlphaColor).toInt()
+ bgDrawable?.draw(canvas)
+ }
+
+ }
+
+
+ private fun drawWeekData(canvas: Canvas) {
+ for (j in 0..6) {
+ val rectF = getRealRectF(0, j)
+ val index = 0 * 7 + j
+ val checkedDateList = nViewPager.getTotalCheckedDateList()
+ val localDate = weekDateList[index]
+ if (nViewPager.isAvailable(localDate)) {
+ if (NDateUtil.isToday(localDate)) {
+ calendarPainter.onDrawToday(canvas, rectF, localDate, checkedDateList)
+ } else {
+ calendarPainter.onDrawCurrentMonthOrWeek(canvas, rectF, localDate, checkedDateList)
+ }
+ } else {
+ calendarPainter.onDrawDisableDate(canvas, rectF, localDate)
+ }
+ }
+ }
+
+ private fun drawMonthDate(canvas: Canvas) {
+
+ for (i in 0 until monthDateList.size / 7) {
+ for (j in 0..6) {
+ val rectF = getRealRectF(i, j)
+ val index = i * 7 + j
+ val checkedDateList = nViewPager.getTotalCheckedDateList()
+ val localDate = monthDateList.get(index)
+ if (nViewPager.isAvailable(localDate)) {
+ if (NDateUtil.isLastMonth(pagerInitDate, localDate) || NDateUtil.isNextMonth(pagerInitDate, localDate)) {
+ calendarPainter.onDrawLastOrNextMonth(canvas, rectF, localDate, checkedDateList)
+ } else if (NDateUtil.isToday(localDate)) {
+ calendarPainter.onDrawToday(canvas, rectF, localDate, checkedDateList)
+ } else {
+ calendarPainter.onDrawCurrentMonthOrWeek(canvas, rectF, localDate, checkedDateList)
+ }
+ } else {
+ calendarPainter.onDrawDisableDate(canvas, rectF, localDate)
+ }
+
+ }
+ }
+ }
+
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ return mGestureDetector.onTouchEvent(event)
+ }
+
+
+ private fun getRectFList(dateList: List): List {
+ val rectFList = arrayListOf()
+ val lineCount = dateList.size / 7
+
+ for (i in 0 until lineCount) {
+ for (j in 0..6) {
+ val rectF = resetRectFSize(RectF(), i, j, dateList)
+ rectFList.add(rectF)
+ }
+ }
+ return rectFList
+ }
+
+
+ private fun getRealRectF(lineIndex: Int, columnIndex: Int): RectF {
+ val index = lineIndex * 7 + columnIndex
+ if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ if (weekRectFList == null) {
+ weekRectFList = getRectFList(weekDateList)
+ }
+ return weekRectFList!![index]
+ } else {
+ if (monthRectFList == null) {
+ monthRectFList = getRectFList(monthDateList)
+ }
+
+ val canvasHeight = nViewPager.getCanvasHeight()
+ if (canvasHeight > nViewPager.getMonthHeight()) {
+ return resetRectFSize(monthRectFList!![index], lineIndex, columnIndex, monthDateList)
+ } else {
+ return monthRectFList!![index]
+ }
+ }
+ }
+
+
+ private fun resetRectFSize(rectF: RectF, lineIndex: Int, columnIndex: Int, dateList: List): RectF {
+
+ val lineCount = dateList.size / 7
+ val canvasHeight = nViewPager.getCanvasHeight()
+
+ if (lineCount == 1 || lineCount == 5) {
+ //周 5行月
+ val rectHeight: Float = canvasHeight / 5
+ rectF.set((columnIndex * width / 7).toFloat(), lineIndex * rectHeight, (columnIndex * width / 7 + width / 7).toFloat(), lineIndex * rectHeight + rectHeight)
+
+ } else if (lineCount == 6) {
+
+ //6行的月份,要第一行和最后一行矩形的中心分别和和5行月份第一行和最后一行矩形的中心对齐
+ //5行一个矩形高度 mHeight/5, 画图可知,4个5行矩形的高度等于5个6行矩形的高度 故:6行的每一个矩形高度是 (mHeight/5)*4/5
+ val rectHeight5 = canvasHeight / 5
+ val rectHeight6 = (canvasHeight / 5 * 4 / 5).toFloat()
+
+ rectF.set(
+ (columnIndex * width / 7).toFloat(),
+ lineIndex * rectHeight6 + (rectHeight5 - rectHeight6) / 2,
+ (columnIndex * width / 7 + width / 7).toFloat(),
+ lineIndex * rectHeight6 + rectHeight6 + (rectHeight5 - rectHeight6) / 2
+ )
+ }
+ return rectF
+ }
+
+
+ fun offsetCanvas(canvasIncreaseOffset: Float) {
+
+ //先计算偏移,并且只有在周往下滑动时才计算)
+ val childY = Math.round(nViewPager.getChildY())
+ if (canvasOffset == -1f && canvasIncreaseOffset < 0 && childY >= weekStateY && childY < monthStateY) {
+ canvasOffset = getHoldHeight()
+ }
+
+ if (nViewPager.getCanvasHeight() == nViewPager.getMonthHeight().toFloat()) {
+ canvasOffset += canvasIncreaseOffset
+ if (canvasOffset < 0) {
+ canvasOffset = 0.0F
+ } else if (canvasOffset > getHoldHeight()) {
+ canvasOffset = getHoldHeight()
+ }
+ } else {
+ canvasOffset = 0f
+ }
+
+ invalidate()
+ }
+
+ fun getHoldHeight(): Float {
+ val monthHeight = nViewPager.getMonthHeight().toFloat()
+ val lineNum = monthDateList.size / 7
+
+ val h = if (lineNum == 5) {
+ val rectHeight5 = (monthHeight / 5)
+ getHoldLine() * rectHeight5
+ } else {
+ val rectHeight6 = (monthHeight / 5 * 4 / 5)
+ getHoldLine() * rectHeight6
+ }
+ return h
+ }
+
+
+ private fun getHoldLine(): Int {
+ val fulcrumDate = nViewPager.fulcrumDate
+ return monthDateList.indexOf(fulcrumDate) / 7
+ }
+
+ fun getFirstLocalDate(): LocalDate {
+ return if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ weekDateList[0]
+ } else {
+ LocalDate.of(pagerInitDate.year, pagerInitDate.monthValue, 1)
+ }
+ }
+
+ fun getCurrPageCheckedDateList(): List {
+ val currentCheckedDateList: MutableList = ArrayList()
+ val totalCheckedDateList = nViewPager.getTotalCheckedDateList()
+ val currDateList = if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ weekDateList
+ } else {
+ monthDateList
+ }
+ currDateList.forEach {
+ if (totalCheckedDateList.contains(it)) {
+ currentCheckedDateList.add(it)
+ }
+ }
+
+ return currentCheckedDateList
+ }
+
+ fun getCurrPagerDateList(): List {
+ return if (nViewPager.getCalendarState() == CalendarState.WEEK) {
+ weekDateList
+ } else {
+ monthDateList
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/calendar/NPagerAdapter.kt b/ncalendar/src/main/java/com/necer/calendar/NPagerAdapter.kt
new file mode 100644
index 00000000..6e605ad3
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/calendar/NPagerAdapter.kt
@@ -0,0 +1,61 @@
+package com.necer.calendar
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.viewpager.widget.PagerAdapter
+import com.necer.enumeration.CalendarState
+import java.time.LocalDate
+
+class NPagerAdapter(localDate: LocalDate, calendarState: CalendarState?, size: Int, currPage: Int) : PagerAdapter() {
+
+
+ private var size: Int = Int.MAX_VALUE
+ private var localDate: LocalDate
+ private var currPage: Int
+
+
+ private var calendarState: CalendarState? = CalendarState.MONTH
+
+ init {
+ this.localDate = localDate
+ this.calendarState = calendarState
+ this.size = size
+ this.currPage = currPage
+ }
+
+ fun setCalendarState(localDate: LocalDate, calendarState: CalendarState, size: Int, currPage: Int) {
+ this.localDate = localDate
+ this.calendarState = calendarState
+ this.size = size
+ this.currPage = currPage
+ notifyDataSetChanged()
+ }
+
+
+ override fun getCount(): Int {
+ return size
+ }
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val calendarView = if (calendarState == CalendarState.WEEK) {
+ NCalendarView(container.context, container, localDate.plusWeeks((position - currPage).toLong()))
+ } else {
+ NCalendarView(container.context, container, localDate.plusMonths((position - currPage).toLong()))
+ }
+ calendarView.tag = position
+ container.addView(calendarView)
+ return calendarView
+ }
+
+ override fun getItemPosition(any: Any): Int {
+ return POSITION_NONE
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/calendar/NViewPager.kt b/ncalendar/src/main/java/com/necer/calendar/NViewPager.kt
new file mode 100644
index 00000000..6003314b
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/calendar/NViewPager.kt
@@ -0,0 +1,488 @@
+package com.necer.calendar
+
+import android.content.Context
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.widget.Toast
+import androidx.viewpager.widget.ViewPager
+import com.necer.R
+import com.necer.enumeration.CalendarState
+import com.necer.enumeration.CheckModel
+import com.necer.enumeration.DateChangeBehavior
+import com.necer.enumeration.MultipleCountModel
+import com.necer.listener.OnCalendarChangedListener
+import com.necer.listener.OnCalendarMultipleChangedListener
+import com.necer.listener.OnClickDisableDateListener
+import com.necer.painter.CalendarPainter
+import com.necer.painter.InnerPainter
+import com.necer.utils.NAttrs
+import com.necer.utils.NDateUtil
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+
+/**
+ *
+ *
+ */
+class NViewPager(context: Context, attrs: AttributeSet?) : ViewPager(context, attrs) {
+
+ private var calendarState: CalendarState? = null
+
+ private var monthHeight = 0
+
+ private val totalCheckedDateList = arrayListOf()
+
+
+ private var calendarPainter: CalendarPainter? = null
+ private lateinit var checkModel: CheckModel
+
+ private var defaultCheckedFirstDate = false //默认选择时,翻页选中第一个日期
+
+
+ private var dateChangeBehavior: DateChangeBehavior = DateChangeBehavior.INITIALIZE
+
+ private var onCalendarChangedListener: OnCalendarChangedListener? = null
+ private var onClickDisableDateListener: OnClickDisableDateListener? = null
+ private var onCalendarMultipleChangedListener: OnCalendarMultipleChangedListener? = null
+
+ private var multipleCountModel: MultipleCountModel? = null
+ private var multipleCount: Int = 0
+
+ private lateinit var startDate: LocalDate
+ private lateinit var endDate: LocalDate
+
+ private val defaultStartDate = LocalDate.parse("1901-01-01")
+ private val defaultEndDateDate = LocalDate.parse("2099-12-31")
+
+ private lateinit var initDate: LocalDate
+
+ lateinit var fulcrumDate: LocalDate
+
+ private var lastCallbackDate: LocalDate? = null
+
+ init {
+
+ addOnPageChangeListener(object : SimpleOnPageChangeListener() {
+ override fun onPageSelected(position: Int) {
+ super.onPageSelected(position)
+ post {
+
+ val nCalendarView = findViewWithTag(currentItem) as? NCalendarView
+ val currentViewInitDate = nCalendarView?.pagerInitDate
+ //算出相差几页
+ var localDate = if (calendarState == CalendarState.WEEK) {
+ val intervalWeek = NDateUtil.getIntervalWeek(fulcrumDate, currentViewInitDate!!, NAttrs.firstDayOfWeek)
+ fulcrumDate.plusWeeks(intervalWeek.toLong())
+ } else {
+ val intervalMonths = NDateUtil.getIntervalMonths(fulcrumDate, currentViewInitDate!!)
+ fulcrumDate.plusMonths(intervalMonths.toLong())
+ }
+
+ localDate = getAvailableDate(localDate)
+
+ if (checkModel == CheckModel.SINGLE_DEFAULT_CHECKED) {
+
+ if (defaultCheckedFirstDate) {
+ localDate = nCalendarView.getFirstLocalDate()
+ }
+
+ totalCheckedDateList.clear()
+ totalCheckedDateList.add(localDate)
+ }
+
+ //重新赋值 fulcrumDate
+ val currPageCheckedList = nCalendarView.getCurrPageCheckedDateList()
+ fulcrumDate = if (currPageCheckedList.isEmpty()) {
+ localDate
+ } else {
+ currPageCheckedList[0]
+ }
+
+ notifyAllView()
+ dateChangedCallBack()
+ }
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {
+ super.onPageScrollStateChanged(state)
+ if (state == SCROLL_STATE_DRAGGING) {
+ dateChangeBehavior = DateChangeBehavior.PAGE
+ }
+
+ }
+ })
+
+ calendarState = CalendarState.valueOf(NAttrs.defaultCalendar)
+ monthHeight = NAttrs.calendarHeight
+ defaultCheckedFirstDate = NAttrs.defaultCheckedFirstDate
+
+ val initDate: LocalDate = LocalDate.now()
+ val startDate = defaultStartDate
+ val endDate = defaultEndDateDate
+ init(startDate, endDate, initDate)
+
+ setCheckMode(CheckModel.SINGLE_DEFAULT_CHECKED)
+
+ }
+
+ private fun init(startDate: LocalDate, endDate: LocalDate, initDate: LocalDate) {
+
+ this.startDate = startDate
+ this.endDate = endDate
+ this.initDate = getAvailableDate(initDate)
+ this.fulcrumDate = this.initDate
+
+ require(!startDate.isAfter(endDate)) { context.getString(R.string.N_start_after_end) }
+ require(!startDate.isBefore(defaultStartDate)) { context.getString(R.string.N_start_before_19010101) }
+ require(!endDate.isAfter(defaultEndDateDate)) { context.getString(R.string.N_end_after_20991231) }
+ require(!(startDate.isAfter(initDate) || endDate.isBefore(initDate))) { context.getString(R.string.N_initialize_date_illegal) }
+
+ val monthTotalPages = NDateUtil.getIntervalMonths(startDate, endDate) + 1
+ val weekTotalPages = NDateUtil.getIntervalWeek(startDate, endDate, NAttrs.firstDayOfWeek) + 1
+
+
+ val totalPages = when (calendarState) {
+ CalendarState.WEEK -> weekTotalPages
+ CalendarState.MONTH -> monthTotalPages
+ CalendarState.MONTH_STRETCH -> monthTotalPages
+ else -> 0
+ }.toInt()
+
+ adapter = NPagerAdapter(initDate, calendarState, totalPages, NDateUtil.getIntervalMonths(startDate, initDate))
+ currentItem = NDateUtil.getIntervalMonths(startDate, initDate)
+
+ }
+
+ fun setDateInterval(startFormatDate: String?, endFormatDate: String?, formatInitializeDate: String?) {
+ val dateFormatter = DateTimeFormatter.ofPattern("yyyy-M-d")
+ init(LocalDate.parse(startFormatDate,dateFormatter), LocalDate.parse(endFormatDate,dateFormatter), LocalDate.parse(formatInitializeDate))
+ }
+
+ fun setDateInterval(startFormatDate: String?, endFormatDate: String?) {
+ val dateFormatter = DateTimeFormatter.ofPattern("yyyy-M-d")
+ init(LocalDate.parse(startFormatDate,dateFormatter), LocalDate.parse(endFormatDate,dateFormatter), LocalDate.now())
+ }
+
+ fun setInitializeDate(localDate: LocalDate) {
+ init(defaultStartDate, defaultEndDateDate, localDate)
+ }
+
+ fun setMultipleCount(multipleCount: Int, multipleCountModel: MultipleCountModel?) {
+ setCheckMode(CheckModel.MULTIPLE)
+ this.multipleCount = multipleCount
+ this.multipleCountModel = multipleCountModel
+ }
+
+ fun setCalendarState(calendarState: CalendarState) {
+ this.calendarState = calendarState
+ if (calendarState == CalendarState.WEEK) {
+ val intervalWeek = NDateUtil.getIntervalWeek(startDate, fulcrumDate, NAttrs.firstDayOfWeek)
+ val weekTotalPages = NDateUtil.getIntervalWeek(startDate, endDate, NAttrs.firstDayOfWeek) + 1
+ (adapter as NPagerAdapter).setCalendarState(fulcrumDate, calendarState, weekTotalPages, intervalWeek)
+ setCurrentItem(intervalWeek, false)
+ } else {
+ val intervalMonth = NDateUtil.getIntervalMonths(startDate, fulcrumDate)
+ val monthTotalPages = NDateUtil.getIntervalMonths(startDate, endDate) + 1
+ (adapter as NPagerAdapter).setCalendarState(fulcrumDate, calendarState, monthTotalPages, intervalMonth)
+ setCurrentItem(intervalMonth, false)
+ }
+
+ }
+
+ override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+ return if (NAttrs.horizontalScrollEnable) {
+ super.onInterceptTouchEvent(ev)
+ } else {
+ false
+ }
+ }
+
+ override fun onTouchEvent(ev: MotionEvent?): Boolean {
+ return if (NAttrs.horizontalScrollEnable) {
+ super.onTouchEvent(ev)
+ } else {
+ false
+ }
+ }
+
+
+ override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
+ if (calendarState == null) {
+ return true
+ }
+ return super.dispatchTouchEvent(ev)
+ }
+
+
+ //点击的日期是否可用
+ fun isAvailable(localDate: LocalDate): Boolean {
+ return !localDate.isBefore(startDate) && !localDate.isAfter(endDate)
+ }
+
+ //日期边界处理
+ private fun getAvailableDate(localDate: LocalDate): LocalDate {
+ return if (localDate.isBefore(startDate)) {
+ startDate
+ } else if (localDate.isAfter(endDate)) {
+ endDate
+ } else {
+ localDate
+ }
+ }
+
+ fun getCalendarState(): CalendarState? {
+ return calendarState
+ }
+
+ fun getCanvasHeight(): Float {
+ return (parent as NCalendar).getCanvasHeight()
+ }
+
+ fun getMonthHeight(): Int {
+ return monthHeight
+ }
+
+ fun getHoldHeight(): Float {
+ val nCalendarView = findViewWithTag(currentItem)
+ return nCalendarView.getHoldHeight()
+ }
+
+
+ fun offsetView(dy: Float) {
+ calendarState = null
+ val nCalendarView = findViewWithTag(currentItem)
+ nCalendarView.offsetCanvas(dy)
+ }
+
+ fun setClickDate(checkedDate: LocalDate) {
+
+ if (calendarState == CalendarState.WEEK) {
+ jump(checkedDate, true, DateChangeBehavior.CLICK)
+ } else {
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ val pagerInitDate = nCalendarView.pagerInitDate
+ if (NDateUtil.isEqualsMonth(checkedDate, pagerInitDate) || !NAttrs.horizontalScrollEnable) {
+ jump(checkedDate, true, DateChangeBehavior.CLICK)
+ } else {
+ if (NAttrs.lastNextMonthClickEnable) {
+ jump(checkedDate, true, DateChangeBehavior.CLICK_PAGE)
+ }
+ }
+ }
+ }
+
+ fun notifyAllView() {
+ //刷新所有页面
+ for (j in 0 until childCount) {
+ (getChildAt(j) as NCalendarView).invalidate()
+ }
+ }
+
+ fun setCheckMode(checkModel: CheckModel) {
+ this.checkModel = checkModel
+
+ totalCheckedDateList.clear()
+ if (checkModel === CheckModel.SINGLE_DEFAULT_CHECKED) {
+ totalCheckedDateList.add(initDate)
+ }
+
+ }
+
+ fun getCheckMode(): CheckModel {
+ return checkModel
+ }
+
+
+ fun getCurrPagerCheckedDateList(): List {
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ return nCalendarView.getCurrPageCheckedDateList()
+ }
+
+ fun getCurrPagerDateList(): List {
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ return nCalendarView.getCurrPagerDateList()
+ }
+
+ fun setCheckedDates(dateList: List) {
+ if (checkModel !== CheckModel.MULTIPLE) {
+ throw RuntimeException(context.getString(R.string.N_set_checked_dates_illegal))
+ }
+
+ if (multipleCountModel != null && dateList.size > multipleCount) {
+ throw RuntimeException(context.getString(R.string.N_set_checked_dates_count_illegal))
+ }
+ totalCheckedDateList.clear()
+ val dateFormatter = DateTimeFormatter.ofPattern("yyyy-M-d")
+
+ try {
+ for (i in dateList.indices) {
+ totalCheckedDateList.add(LocalDate.parse(dateList[i],dateFormatter))
+ }
+ } catch (e: Exception) {
+ throw IllegalArgumentException(context.getString(R.string.N_date_format_illegal))
+ }
+ }
+
+
+ fun getTotalCheckedDateList(): List {
+ return totalCheckedDateList
+ }
+
+ fun setCalendarPainter(calendarPainter: CalendarPainter?) {
+ this.calendarPainter = calendarPainter
+ }
+
+ fun setOnCalendarChangedListener(onCalendarChangedListener: OnCalendarChangedListener?) {
+ this.onCalendarChangedListener = onCalendarChangedListener
+ }
+
+ fun setOnClickDisableDateListener(onClickDisableDateListener: OnClickDisableDateListener?) {
+ this.onClickDisableDateListener = onClickDisableDateListener
+ }
+
+ fun setOnCalendarMultipleChangedListener(onCalendarMultipleChangedListener: OnCalendarMultipleChangedListener?) {
+ this.onCalendarMultipleChangedListener = onCalendarMultipleChangedListener
+ }
+
+ fun getCalendarPainter(): CalendarPainter {
+ if (calendarPainter == null) {
+ calendarPainter = InnerPainter(context, parent as NCalendar)
+ }
+ return calendarPainter!!
+ }
+
+ fun getChildY(): Float {
+ return (parent as NCalendar).getChildY()
+ }
+
+ fun getMonthStateY(): Int {
+ return (parent as NCalendar).getMonthStateY()
+ }
+
+ fun getWeekStateY(): Int {
+ return (parent as NCalendar).getWeekStateY()
+ }
+
+ fun toLastPager() {
+ if (!NAttrs.horizontalScrollEnable) {
+ Toast.makeText(context, resources.getString(R.string.N_horizontalScrollString), Toast.LENGTH_SHORT).show()
+ return
+ }
+ dateChangeBehavior = DateChangeBehavior.API
+ currentItem -= 1
+ }
+
+ fun toNextPager() {
+ if (!NAttrs.horizontalScrollEnable) {
+ Toast.makeText(context, resources.getString(R.string.N_horizontalScrollString), Toast.LENGTH_SHORT).show()
+ return
+ }
+ dateChangeBehavior = DateChangeBehavior.API
+ currentItem += 1
+ }
+
+ fun toToday() {
+ jump(LocalDate.now(), true, DateChangeBehavior.API)
+ }
+
+
+ fun jumpDate(localDate: LocalDate,isCheck: Boolean) {
+ jump(localDate, isCheck, DateChangeBehavior.API)
+ }
+
+ private fun jump(localDate: LocalDate, isCheck: Boolean, dateChangeBehavior: DateChangeBehavior) {
+
+ if (!isAvailable(localDate)) {
+ if (onClickDisableDateListener == null) {
+ Toast.makeText(context, if (TextUtils.isEmpty(NAttrs.disabledString)) resources.getString(R.string.N_disabledString) else NAttrs.disabledString, Toast.LENGTH_SHORT).show()
+ } else {
+ onClickDisableDateListener?.onClickDisableDate(localDate)
+ }
+ } else {
+
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ val currentViewInitDate = nCalendarView.pagerInitDate
+ val indexOffset = if (calendarState == CalendarState.WEEK) {
+ NDateUtil.getIntervalWeek(localDate, currentViewInitDate, NAttrs.firstDayOfWeek)
+ } else {
+ NDateUtil.getIntervalMonths(localDate, currentViewInitDate)
+ }
+
+ if (indexOffset != 0 && !NAttrs.horizontalScrollEnable) {
+ Toast.makeText(context, resources.getString(R.string.N_horizontalScrollString), Toast.LENGTH_SHORT).show()
+ return
+ }
+
+ this.fulcrumDate = localDate
+ this.dateChangeBehavior = dateChangeBehavior
+
+
+ if (isCheck) {
+ if (checkModel === CheckModel.MULTIPLE) {
+ if (!totalCheckedDateList.contains(localDate)) {
+ if (totalCheckedDateList.size == multipleCount && multipleCountModel === MultipleCountModel.FULL_CLEAR) {
+ totalCheckedDateList.clear()
+ } else if (totalCheckedDateList.size == multipleCount && multipleCountModel === MultipleCountModel.FULL_REMOVE_FIRST) {
+ totalCheckedDateList.removeAt(0)
+ }
+ totalCheckedDateList.add(localDate)
+ } else {
+ totalCheckedDateList.remove(localDate)
+ }
+ } else {
+ //单选
+ totalCheckedDateList.clear()
+ totalCheckedDateList.add(localDate)
+ }
+ }
+
+
+ if (indexOffset == 0) {
+ // notifyAllView()
+ //只刷新当前页面即可,其他页面会在刷新adapter的时候自动回调
+ nCalendarView.invalidate()
+ dateChangedCallBack()
+ } else {
+ setCurrentItem(currentItem - indexOffset, Math.abs(indexOffset) == 1)
+ }
+ }
+ }
+
+ /**
+ * 回调说明
+ * 1、SINGLE_DEFAULT_CHECKED 每页单选时 每次一变化都回调了,避免多次回调 ,做个判断
+ * 2、其他模式 由于选中是用户行为,周日历时没有选中的,但是变成月时,日期多了28或者35个,是可能存在选中的,故不做限制直接回调
+ */
+ private fun dateChangedCallBack() {
+ when (checkModel) {
+ CheckModel.SINGLE_DEFAULT_CHECKED -> {
+
+ val localDate = totalCheckedDateList[0]
+ if (lastCallbackDate != localDate) {
+ onCalendarChangedListener?.onCalendarChange(localDate.year, localDate.monthValue, localDate, dateChangeBehavior)
+ lastCallbackDate = localDate
+ }
+ }
+ CheckModel.SINGLE_DEFAULT_UNCHECKED -> {
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ val pagerInitDate = nCalendarView.pagerInitDate
+ val currPageCheckedDateList = nCalendarView.getCurrPageCheckedDateList()
+ val checkedDate = if (currPageCheckedDateList.isEmpty()) null else currPageCheckedDateList[0]
+
+ onCalendarChangedListener?.onCalendarChange(pagerInitDate.year, pagerInitDate.monthValue, checkedDate, dateChangeBehavior)
+
+ }
+ CheckModel.MULTIPLE -> {
+ val nCalendarView = findViewWithTag(currentItem) as NCalendarView
+ val localDate = nCalendarView.pagerInitDate
+ val currPageCheckedDateList = nCalendarView.getCurrPageCheckedDateList()
+ onCalendarMultipleChangedListener?.onCalendarChange(localDate.year, localDate.monthValue, currPageCheckedDateList, totalCheckedDateList, dateChangeBehavior)
+ }
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/calendar/NWeekBar.kt b/ncalendar/src/main/java/com/necer/calendar/NWeekBar.kt
new file mode 100644
index 00000000..e0e279cd
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/calendar/NWeekBar.kt
@@ -0,0 +1,42 @@
+package com.necer.calendar
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Rect
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import com.necer.utils.NAttrs
+
+/**
+ * Created by necer on 2018/12/24.
+ */
+class NWeekBar(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) {
+ private var days = arrayOf("日", "一", "二", "三", "四", "五", "六")
+
+ @SuppressLint("DrawAllocation")
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+
+ canvas.drawColor(NAttrs.weekBarBackgroundColor)
+
+ paint.textAlign = Paint.Align.CENTER
+ paint.color = NAttrs.weekBarTextColor
+ paint.textSize = NAttrs.weekBarTextSize
+ for (i in days.indices) {
+ val rect = Rect(i * width / days.size, 0, (i + 1) * width / days.size, height)
+ val fontMetrics = paint.fontMetrics
+ val top = fontMetrics.top
+ val bottom = fontMetrics.bottom
+ val baseLineY = (rect.centerY() - top / 2 - bottom / 2).toInt()
+ val day = if (NAttrs.firstDayOfWeek == NAttrs.MONDAY) {
+ val j = i + 1
+ days[if (j > days.size - 1) 0 else j]
+ } else {
+ days[i]
+ }
+ canvas.drawText(day, rect.centerX().toFloat(), baseLineY.toFloat(), paint)
+ }
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/calendar/WeekCalendar.java b/ncalendar/src/main/java/com/necer/calendar/WeekCalendar.java
deleted file mode 100644
index 1667646d..00000000
--- a/ncalendar/src/main/java/com/necer/calendar/WeekCalendar.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.necer.calendar;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import android.util.AttributeSet;
-
-import com.necer.adapter.BasePagerAdapter;
-import com.necer.adapter.WeekPagerAdapter;
-import com.necer.utils.CalendarUtil;
-
-import org.joda.time.LocalDate;
-
-
-/**
- *
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public class WeekCalendar extends BaseCalendar {
-
- public WeekCalendar(@NonNull Context context, @Nullable AttributeSet attributeSet) {
- super(context, attributeSet);
- }
-
- @Override
- protected BasePagerAdapter getPagerAdapter(Context context, BaseCalendar baseCalendar) {
- return new WeekPagerAdapter(context, baseCalendar);
- }
-
- @Override
- protected int getTwoDateCount(LocalDate startDate, LocalDate endDate, int type) {
- return CalendarUtil.getIntervalWeek(startDate, endDate, type);
- }
-
- @Override
- protected LocalDate getIntervalDate(LocalDate localDate, int count) {
- return localDate.plusWeeks(count);
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/drawable/TextDrawable.java b/ncalendar/src/main/java/com/necer/drawable/TextDrawable.java
deleted file mode 100644
index 21d5f4a2..00000000
--- a/ncalendar/src/main/java/com/necer/drawable/TextDrawable.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.necer.drawable;
-
-import android.annotation.SuppressLint;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- *
- * @author necer
- * @date 2020/3/27
- */
-public class TextDrawable extends Drawable {
-
-
- private Paint mTextPaint;
- private String mText;
-
- public TextDrawable(float textSize) {
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setTextSize(textSize);
- mTextPaint.setTextAlign(Paint.Align.CENTER);
- }
-
-
- public void setText(String text) {
- this.mText = text;
- }
-
- @Override
- public void draw(@NonNull Canvas canvas) {
- Rect rect = getBounds();
- canvas.drawColor(Color.WHITE);
- canvas.drawText(mText, rect.centerX(), getTextBaseLineY(rect.centerY()), mTextPaint);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mTextPaint.setAlpha(alpha);
- }
-
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
- mTextPaint.setColorFilter(colorFilter);
- }
-
- @SuppressLint("WrongConstant")
- @Override
- public int getOpacity() {
- return 0;
- }
-
-
- private float getTextBaseLineY(float centerY) {
- Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
- return centerY - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/drawable/TextDrawable.kt b/ncalendar/src/main/java/com/necer/drawable/TextDrawable.kt
new file mode 100644
index 00000000..736cd140
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/drawable/TextDrawable.kt
@@ -0,0 +1,53 @@
+package com.necer.drawable
+
+import android.annotation.SuppressLint
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.Paint
+import android.graphics.drawable.Drawable
+import com.necer.utils.NAttrs
+
+/**
+ *
+ * @author necer
+ * @date 2020/3/27
+ */
+class TextDrawable() : Drawable() {
+ private val textPaint: Paint = Paint()
+ private var text: String? = null
+
+ init {
+ textPaint.isAntiAlias = true
+ textPaint.textAlign = Paint.Align.CENTER
+ textPaint.textSize = NAttrs.numberBackgroundTextSize
+ textPaint.color = NAttrs.numberBackgroundTextColor
+ textPaint.alpha = NAttrs.backgroundAlphaColor
+ }
+
+ fun setText(text: String?) {
+ this.text = text
+ }
+
+ override fun draw(canvas: Canvas) {
+ val rect = bounds
+ canvas.drawText(text!!, rect.centerX().toFloat(), getTextBaseLineY(rect.centerY().toFloat()), textPaint)
+ }
+
+ override fun setAlpha(alpha: Int) {
+ textPaint.alpha = alpha
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ textPaint.colorFilter = colorFilter
+ }
+
+ @SuppressLint("WrongConstant")
+ override fun getOpacity(): Int {
+ return 0
+ }
+
+ private fun getTextBaseLineY(centerY: Float): Float {
+ val fontMetrics = textPaint.fontMetrics
+ return centerY - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/entity/CalendarDate.java b/ncalendar/src/main/java/com/necer/entity/CalendarDate.java
deleted file mode 100644
index c690936d..00000000
--- a/ncalendar/src/main/java/com/necer/entity/CalendarDate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.necer.entity;
-
-import org.joda.time.LocalDate;
-
-import java.io.Serializable;
-
-/***
- * 日历日期 包含公历、农历、节气、节日
- * @author necer
- */
-public class CalendarDate implements Serializable {
-
- /**
- * 公历日期
- */
- public LocalDate localDate;
-
- /**
- * 农历
- */
- public Lunar lunar;
-
- /**
- * 公历节日
- */
- public String solarHoliday;
-
- /**
- * 农历节日
- */
- public String lunarHoliday;
-
- /**
- * 节气
- */
- public String solarTerm;
-}
diff --git a/ncalendar/src/main/java/com/necer/entity/Lunar.java b/ncalendar/src/main/java/com/necer/entity/Lunar.java
deleted file mode 100644
index 05677087..00000000
--- a/ncalendar/src/main/java/com/necer/entity/Lunar.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.necer.entity;
-
-import java.io.Serializable;
-
-/**
- *
- * @author necer
- * @date 2018/11/16
- */
-public class Lunar implements Serializable {
-
- /**
- * 是否闰年
- */
- public boolean isLeap;
-
- /**
- * 农历的天
- */
- public int lunarDay;
-
- /**
- * 农历的月
- */
- public int lunarMonth;
-
- /**
- * 农历年
- */
- public int lunarYear;
-
- /**
- * 闰月
- */
- public int leapMonth;
-
-
- /**
- * 农历位置需要绘制的文字
- */
- public String lunarOnDrawStr;
-
- /**
- * 农历天 描述 廿二等
- */
- public String lunarDayStr;
-
- /**
- * 农历月 描述
- */
- public String lunarMonthStr;
-
- /**
- * 农历年 描述
- */
- public String lunarYearStr;
-
- /**
- *生肖
- */
- public String animals;
-
- /**
- * 天干地支
- */
- public String chineseEra;
-
-}
diff --git a/ncalendar/src/main/java/com/necer/enumeration/CalendarBuild.java b/ncalendar/src/main/java/com/necer/enumeration/CalendarBuild.java
deleted file mode 100644
index 68f0ac36..00000000
--- a/ncalendar/src/main/java/com/necer/enumeration/CalendarBuild.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.necer.enumeration;
-
-import java.io.Serializable;
-
-/**
- * 日历构造类型 绘制draw 适配器 adapter
- * @author necer
- */
-public enum CalendarBuild implements Serializable {
-
- /**
- * 绘制 -> CalendarView
- */
- DRAW,
-
- /**
- * 适配器 -> CalendarView2
- */
- ADAPTER
-}
diff --git a/ncalendar/src/main/java/com/necer/enumeration/CalendarState.java b/ncalendar/src/main/java/com/necer/enumeration/CalendarState.java
deleted file mode 100644
index aa8cdd57..00000000
--- a/ncalendar/src/main/java/com/necer/enumeration/CalendarState.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.necer.enumeration;
-
-import java.io.Serializable;
-
-/**
- * 日历状态
- *
- * @author necer
- */
-public enum CalendarState implements Serializable {
-
- /**
- * 折叠日历周状态
- */
- WEEK(100),
-
- /**
- * 折叠日历月状态
- */
- MONTH(101),
-
- /**
- * 折叠日历月拉伸状态
- */
- MONTH_STRETCH(102);
-
- private int value;
-
- CalendarState(int value) {
- this.value = value;
- }
-
- public int getValue() {
- return value;
- }
-
- public static CalendarState valueOf(int value) {
- switch (value) {
- case 100:
- return CalendarState.WEEK;
- case 101:
- return CalendarState.MONTH;
- case 102:
- return CalendarState.MONTH_STRETCH;
- default:
- return null;
- }
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/enumeration/CalendarState.kt b/ncalendar/src/main/java/com/necer/enumeration/CalendarState.kt
new file mode 100644
index 00000000..5d297574
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/enumeration/CalendarState.kt
@@ -0,0 +1,40 @@
+package com.necer.enumeration
+
+import java.io.Serializable
+
+/**
+ * 日历状态
+ *
+ * @author necer
+ */
+enum class CalendarState(private val value: Int) : Serializable {
+ /**
+ * 折叠日历周状态
+ */
+ WEEK(100),
+
+ /**
+ * 折叠日历月状态
+ */
+ MONTH(101),
+
+ /**
+ * 折叠日历月拉伸状态
+ */
+ MONTH_STRETCH(102);
+
+ open fun getValue(): Int {
+ return value
+ }
+
+ companion object {
+ fun valueOf(value: Int): CalendarState? {
+ return when (value) {
+ 100 -> WEEK
+ 101 -> MONTH
+ 102 -> MONTH_STRETCH
+ else -> null
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/enumeration/CalendarType.java b/ncalendar/src/main/java/com/necer/enumeration/CalendarType.java
deleted file mode 100644
index b3d580fa..00000000
--- a/ncalendar/src/main/java/com/necer/enumeration/CalendarType.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.necer.enumeration;
-
-import java.io.Serializable;
-
-/**
- * @author necer
- */
-
-public enum CalendarType implements Serializable {
-
- /**
- * 月日历
- */
- MONTH,
-
- /**
- * 周日历
- */
- WEEK
-}
diff --git a/ncalendar/src/main/java/com/necer/helper/CalendarHelper.java b/ncalendar/src/main/java/com/necer/helper/CalendarHelper.java
deleted file mode 100644
index 7b83068e..00000000
--- a/ncalendar/src/main/java/com/necer/helper/CalendarHelper.java
+++ /dev/null
@@ -1,280 +0,0 @@
-package com.necer.helper;
-
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.CalendarType;
-import com.necer.painter.CalendarAdapter;
-import com.necer.painter.CalendarBackground;
-import com.necer.painter.CalendarPainter;
-import com.necer.utils.CalendarUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author necer
- */
-public class CalendarHelper {
-
- //行数
- private int mLineNum;
- //当前页面的初始化日期
- private LocalDate mPagerInitialDate;
- private BaseCalendar mCalendar;
-
- private CalendarType mCalendarType;
- //日历背景矩形
- private Rect mBackgroundRect;
- //当前页面选中的日期
- private List mTotalCheckedListDate;
- //页面的数据集合
- private List mDateList;
- private List mRectFList;
- private GestureDetector mGestureDetector;
-
- public CalendarHelper(BaseCalendar calendar, LocalDate pagerInitialDate, CalendarType calendarType) {
- this.mCalendar = calendar;
- this.mCalendarType = calendarType;
- this.mPagerInitialDate = pagerInitialDate;
- mDateList = calendarType == CalendarType.MONTH
- ? CalendarUtil.getMonthCalendar(mPagerInitialDate, mCalendar.getFirstDayOfWeek(), mCalendar.isAllMonthSixLine())
- : CalendarUtil.getWeekCalendar(mPagerInitialDate, mCalendar.getFirstDayOfWeek());
-
- mLineNum = mDateList.size() / 7;
-
- mRectFList = getLocationRectFList();
-
- mTotalCheckedListDate = mCalendar.getTotalCheckedDateList();
-
- mBackgroundRect = new Rect(0, 0, calendar.getMeasuredWidth(), calendar.getMeasuredHeight());
-
- GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onDown(MotionEvent e) {
- return true;
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- for (int i = 0; i < mRectFList.size(); i++) {
- RectF rectF = mRectFList.get(i);
- if (rectF.contains((int) e.getX(), (int) e.getY())) {
- LocalDate clickDate = mDateList.get(i);
- dealClickDate(clickDate);
- break;
- }
- }
- return true;
- }
- };
- mGestureDetector = new GestureDetector(calendar.getContext(), mSimpleOnGestureListener);
- }
-
- /**
- * 分配空间
- *
- * @return 返回每个日期的绘制矩形集合
- */
- private List getLocationRectFList() {
- List rectFList = new ArrayList<>();
- for (int i = 0; i < mDateList.size(); i++) {
- rectFList.add(new RectF());
- }
- return rectFList;
- }
-
-
- /**
- * 获取当前的位置,拉伸日历时会变化,其他状态不会变
- *
- * @param lineIndex 行
- * @param columnIndex 列
- * @return 返回所属行列的矩形
- */
- public RectF getRealRectF(int lineIndex, int columnIndex) {
- int index = lineIndex * 7 + columnIndex;
- return resetRectFSize(mRectFList.get(index), lineIndex, columnIndex);
- }
-
- /**
- * 重新确定位置,拉伸日历用到
- */
- public void resetRectFSize() {
- for (int i = 0; i < mLineNum; i++) {
- for (int j = 0; j < 7; j++) {
- int index = i * 7 + j;
- resetRectFSize(mRectFList.get(index), i, j);
- }
- }
- }
-
- private RectF resetRectFSize(RectF rectF, int lineIndex, int columnIndex) {
- //矩形重新确定确定位置
- float width = mCalendar.getMeasuredWidth();
- float height = mCalendar.getMeasuredHeight();
- //为每个矩形确定位置
- if (mLineNum == 5 || mLineNum == 1) {
- //5行的月份,5行矩形平分view的高度 mLineNum==1是周的情况
- float rectHeight = height / mLineNum;
- rectF.set(columnIndex * width / 7, lineIndex * rectHeight, columnIndex * width / 7 + width / 7, lineIndex * rectHeight + rectHeight);
- } else {
- //6行的月份,要第一行和最后一行矩形的中心分别和和5行月份第一行和最后一行矩形的中心对齐
- //5行一个矩形高度 mHeight/5, 画图可知,4个5行矩形的高度等于5个6行矩形的高度 故:6行的每一个矩形高度是 (mHeight/5)*4/5
- float rectHeight5 = height / 5;
- float rectHeight6 = (height / 5) * 4 / 5;
- rectF.set(columnIndex * width / 7, lineIndex * rectHeight6 + (rectHeight5 - rectHeight6) / 2, columnIndex * width / 7 + width / 7, lineIndex * rectHeight6 + rectHeight6 + (rectHeight5 - rectHeight6) / 2);
- }
- return rectF;
- }
-
- public int getLineNum() {
- return mLineNum;
- }
-
- public LocalDate getPagerInitialDate() {
- return mPagerInitialDate;
- }
-
- public CalendarType getCalendarType() {
- return mCalendarType;
- }
-
- public int getCalendarHeight() {
- return mCalendar.getMeasuredHeight();
- }
-
-
- public Rect getBackgroundRectF() {
- return mBackgroundRect;
- }
-
- public CalendarPainter getCalendarPainter() {
- return mCalendar.getCalendarPainter();
- }
-
- public CalendarBackground getCalendarBackground() {
- return mCalendar.getCalendarBackground();
- }
-
- public CalendarAdapter getCalendarAdapter() {
- return mCalendar.getCalendarAdapter();
- }
-
- public List getAllSelectListDate() {
- return mTotalCheckedListDate;
- }
-
- public List getDateList() {
- return mDateList;
- }
-
- public LocalDate getMiddleLocalDate() {
- return mDateList.get((mDateList.size() / 2) + 1);
- }
-
- /**
- * @param localDate 日期
- * @return localDate 到顶部的距离
- */
- public int getDistanceFromTop(LocalDate localDate) {
- int monthCalendarOffset;
- //选中的是第几行 对于没有选中的默认折叠中心是第一行,有选中的默认折叠中心是选中的第一个日期
- int checkedIndex = mDateList.indexOf(localDate) / 7;
- if (mLineNum == 5) {
- //5行的月份
- monthCalendarOffset = mCalendar.getMeasuredHeight() / 5 * checkedIndex;
- } else {
- int rectHeight6 = (mCalendar.getMeasuredHeight() / 5) * 4 / 5;
- monthCalendarOffset = rectHeight6 * checkedIndex;
- }
- return monthCalendarOffset;
- }
-
- /**
- * @return 获取中心点 ,即月周切换的中心日期
- */
- public LocalDate getPivotDate() {
- LocalDate today = new LocalDate();
- if (getCurrentSelectDateList().size() != 0) {
- return getCurrentSelectDateList().get(0);
- } else if (mDateList.contains(today)) {
- return today;
- } else {
- return mDateList.get(0);
- }
- }
-
- /**
- * @return 中心点到顶部的距离
- */
- public int getPivotDistanceFromTop() {
- return getDistanceFromTop(getPivotDate());
- }
-
- public List getCurrentSelectDateList() {
- List currentSelectDateList = new ArrayList<>();
- for (int i = 0; i < mDateList.size(); i++) {
- LocalDate localDate = mDateList.get(i);
- if (mTotalCheckedListDate != null && mTotalCheckedListDate.contains(localDate)) {
- currentSelectDateList.add(localDate);
- }
- }
- return currentSelectDateList;
- }
-
- public List getCurrentDateList() {
- return mDateList;
- }
-
- private void dealClickDate(LocalDate localDate) {
- if (mCalendarType == CalendarType.MONTH && CalendarUtil.isLastMonth(localDate, mPagerInitialDate)) {
- mCalendar.onClickLastMonthDate(localDate);
- } else if (mCalendarType == CalendarType.MONTH && CalendarUtil.isNextMonth(localDate, mPagerInitialDate)) {
- mCalendar.onClickNextMonthDate(localDate);
- } else {
- mCalendar.onClickCurrentMonthOrWeekDate(localDate);
- }
- }
-
-
- public LocalDate getCurrPagerFirstDate() {
- if (mCalendarType == CalendarType.MONTH) {
- return new LocalDate(mPagerInitialDate.getYear(), mPagerInitialDate.getMonthOfYear(), 1);
- } else {
- return mDateList.get(0);
- }
- }
-
- public boolean isAvailableDate(LocalDate localDate) {
- return mCalendar.isAvailable(localDate);
- }
-
- public boolean isCurrentMonthOrWeek(LocalDate localDate) {
- if (mCalendarType == CalendarType.MONTH) {
- return CalendarUtil.isEqualsMonth(localDate, mPagerInitialDate);
- } else {
- return mDateList.contains(localDate);
- }
- }
-
-
- public boolean onTouchEvent(MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
-
-
- /**
- * 背景的初始位置为月日历的高度-周日的高度
- */
- public int getInitialDistance() {
- return mCalendar.getMeasuredHeight() * 4 / 5;
- }
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/listener/OnCalendarChangedListener.java b/ncalendar/src/main/java/com/necer/listener/OnCalendarChangedListener.java
index 2f0c1bcc..6411c578 100644
--- a/ncalendar/src/main/java/com/necer/listener/OnCalendarChangedListener.java
+++ b/ncalendar/src/main/java/com/necer/listener/OnCalendarChangedListener.java
@@ -1,9 +1,9 @@
package com.necer.listener;
-import com.necer.calendar.BaseCalendar;
+
import com.necer.enumeration.DateChangeBehavior;
-import org.joda.time.LocalDate;
+import java.time.LocalDate;
/**
* 日期变化回调
@@ -14,14 +14,5 @@
public interface OnCalendarChangedListener {
- /**
- * 单选模式 日历变化回调,月日历、周日历、折叠日历(NCalendar)都用这一个回调
- *
- * @param baseCalendar 日历对象,MonthCalendar和WeekCalendar
- * @param year 日历当前页面中间日期->年
- * @param month 日历当前页面中间日期->月
- * @param localDate 日历当前页面选中日期,有选中则返回选中日期,无选中则返回null
- * @param dateChangeBehavior 日历变化行为 参照 DateChangeBehavior
- */
- void onCalendarChange(BaseCalendar baseCalendar, int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior);
+ void onCalendarChange(int year, int month, LocalDate localDate, DateChangeBehavior dateChangeBehavior);
}
diff --git a/ncalendar/src/main/java/com/necer/listener/OnCalendarMultipleChangedListener.java b/ncalendar/src/main/java/com/necer/listener/OnCalendarMultipleChangedListener.java
index 1bedbdf2..900588c2 100644
--- a/ncalendar/src/main/java/com/necer/listener/OnCalendarMultipleChangedListener.java
+++ b/ncalendar/src/main/java/com/necer/listener/OnCalendarMultipleChangedListener.java
@@ -1,12 +1,12 @@
package com.necer.listener;
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.DateChangeBehavior;
-import org.joda.time.LocalDate;
+import com.necer.enumeration.DateChangeBehavior;
+import java.time.LocalDate;
import java.util.List;
+
/**
* @author necer
* @date 2017/7/4
@@ -18,12 +18,11 @@ public interface OnCalendarMultipleChangedListener {
/**
* 多选模式 日历变化回调,月日历、周日历、折叠日历(miui9,miui10,emui)都用这一个回调
*
- * @param baseCalendar 日历对象,MonthCalendar和WeekCalendar
* @param year 日历当前页面中间日期->年
* @param month 日历当前页面中间日期->月
* @param currPagerCheckedList 当前页面选中的日期集合,无选中则为空集合
* @param totalCheckedList 日历总共的选中集合,无选中则为空集合
* @param dateChangeBehavior 日历变化行为 参照 DateChangeBehavior
*/
- void onCalendarChange(BaseCalendar baseCalendar, int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior);
+ void onCalendarChange(int year, int month, List currPagerCheckedList, List totalCheckedList, DateChangeBehavior dateChangeBehavior);
}
diff --git a/ncalendar/src/main/java/com/necer/listener/OnCalendarStateChangedListener.java b/ncalendar/src/main/java/com/necer/listener/OnCalendarStateChangedListener.java
index c2264fc4..0656161e 100644
--- a/ncalendar/src/main/java/com/necer/listener/OnCalendarStateChangedListener.java
+++ b/ncalendar/src/main/java/com/necer/listener/OnCalendarStateChangedListener.java
@@ -1,5 +1,6 @@
package com.necer.listener;
+
import com.necer.enumeration.CalendarState;
/**
diff --git a/ncalendar/src/main/java/com/necer/listener/OnClickDisableDateListener.java b/ncalendar/src/main/java/com/necer/listener/OnClickDisableDateListener.java
index 91eb900c..ffb2badf 100644
--- a/ncalendar/src/main/java/com/necer/listener/OnClickDisableDateListener.java
+++ b/ncalendar/src/main/java/com/necer/listener/OnClickDisableDateListener.java
@@ -1,6 +1,7 @@
package com.necer.listener;
-import org.joda.time.LocalDate;
+
+import java.time.LocalDate;
/**
* 点击不可用的日期对调
diff --git a/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.java b/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.java
deleted file mode 100644
index 8850ed97..00000000
--- a/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.necer.listener;
-
-import android.animation.Animator;
-
-/**
- * @author necer
- */
-public class OnEndAnimatorListener implements Animator.AnimatorListener {
- @Override
- public void onAnimationStart(Animator animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
-
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
-
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
-
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.kt b/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.kt
new file mode 100644
index 00000000..4b6df298
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/listener/OnEndAnimatorListener.kt
@@ -0,0 +1,13 @@
+package com.necer.listener
+
+import android.animation.Animator
+
+/**
+ * @author necer
+ */
+open class OnEndAnimatorListener : Animator.AnimatorListener {
+ override fun onAnimationStart(animation: Animator) {}
+ override fun onAnimationEnd(animation: Animator) {}
+ override fun onAnimationCancel(animation: Animator) {}
+ override fun onAnimationRepeat(animation: Animator) {}
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/listener/OnMWDateChangeListener.java b/ncalendar/src/main/java/com/necer/listener/OnMWDateChangeListener.java
deleted file mode 100644
index 57e72d87..00000000
--- a/ncalendar/src/main/java/com/necer/listener/OnMWDateChangeListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.necer.listener;
-
-import com.necer.calendar.BaseCalendar;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-/**
- * 月周切换时,中心点变化的回调
- *
- * @author necer
- */
-public interface OnMWDateChangeListener {
-
- /**
- * 月周切换时,中心点变化的回调
- *
- * @param baseCalendar 日历对象
- * @param localDate 当前页面中心点日期
- * @param totalCheckedDateList 所有选中的集合
- */
- void onMwDateChange(BaseCalendar baseCalendar, LocalDate localDate, List totalCheckedDateList);
-}
diff --git a/ncalendar/src/main/java/com/necer/painter/CalendarAdapter.java b/ncalendar/src/main/java/com/necer/painter/CalendarAdapter.java
deleted file mode 100644
index c1c6b32b..00000000
--- a/ncalendar/src/main/java/com/necer/painter/CalendarAdapter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.necer.painter;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import com.necer.R;
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-/**
- * @author necer
- */
-public abstract class CalendarAdapter {
-
-
- /**
- * 获取日历item的View
- */
- public abstract View getCalendarItemView(Context context);
-
-
- /**
- * 绑定今天的数据
- *
- * @param calendarItemView getCalendarItemView()方法获取的 View
- * @param localDate 今天的日期
- * @param totalCheckedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
- */
- public abstract void onBindToadyView(View calendarItemView, LocalDate localDate, List totalCheckedDateList);
-
- /**
- * 绑定当前月或周的日期
- *
- * @param calendarItemView getCalendarItemView()方法获取的 View
- * @param localDate 月日历-> 当前页面月份中的每个日期(内部是循环处理)
- * 周日历-> 当前页面一周中的每个日期(内部是循环处理)
- * @param totalCheckedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
- */
- public abstract void onBindCurrentMonthOrWeekView(View calendarItemView, LocalDate localDate, List totalCheckedDateList);
-
- /**
- * 绑定上下月的数据 周日历可不用实现
- *
- * @param calendarItemView getCalendarItemView()方法获取的 View
- * @param localDate 月日历-> 当前页面上一月、下一月中的每个日期(内部是循环处理)
- * 周日里-> 周日历无需实现此方法
- * @param totalCheckedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
- */
- public abstract void onBindLastOrNextMonthView(View calendarItemView, LocalDate localDate, List totalCheckedDateList);
-
- /**
- * 绑定不可用的日期数据,和方法setDateInterval(startFormatDate, endFormatDate)对应,
- * 如果没有使用setDateInterval设置日期范围 此方法不用实现
- *
- * @param calendarItemView getCalendarItemView()方法获取的 View
- * @param localDate 不可用的日期
- */
- public void onBindDisableDateView(View calendarItemView, LocalDate localDate) {
-
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/painter/CalendarBackground.java b/ncalendar/src/main/java/com/necer/painter/CalendarBackground.java
deleted file mode 100644
index 81833347..00000000
--- a/ncalendar/src/main/java/com/necer/painter/CalendarBackground.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.necer.painter;
-
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-
-import org.joda.time.LocalDate;
-
-
-/**
- * @author necer
- * @date 2020/3/27
- */
-public interface CalendarBackground {
-
- /**
- * 月日历和周日历的背景,背景用 Drawable 实现
- *
- * @param localDate 当前页面 中心点的日期
- * @param currentDistance 月周折叠日历中当前滑动的距离
- * @param totalDistance 月周折叠日历中可滑动的总距离
- * @return 返回日历背景Drawable
- */
- Drawable getBackgroundDrawable(LocalDate localDate, int currentDistance, int totalDistance);
-
-}
diff --git a/ncalendar/src/main/java/com/necer/painter/CalendarPainter.java b/ncalendar/src/main/java/com/necer/painter/CalendarPainter.kt
similarity index 50%
rename from ncalendar/src/main/java/com/necer/painter/CalendarPainter.java
rename to ncalendar/src/main/java/com/necer/painter/CalendarPainter.kt
index 87555984..e323ed67 100644
--- a/ncalendar/src/main/java/com/necer/painter/CalendarPainter.java
+++ b/ncalendar/src/main/java/com/necer/painter/CalendarPainter.kt
@@ -1,21 +1,14 @@
-package com.necer.painter;
+package com.necer.painter
-import android.graphics.Canvas;
-import android.graphics.RectF;
-
-import com.necer.view.ICalendarView;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
+import android.graphics.Canvas
+import android.graphics.RectF
+import java.time.LocalDate
/**
* @author necer
* @date 2019/1/3
*/
-public interface CalendarPainter {
-
-
+interface CalendarPainter {
/**
* 绘制今天的日期
*
@@ -23,10 +16,10 @@ public interface CalendarPainter {
* @param rectF 今天日期的位置矩形
* @param localDate 今天的日期
* @param checkedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
+ * 单选模式中,集合中最多只有一个元素,
+ * 多选模式中,可以有多个元素
*/
- void onDrawToday(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList);
+ fun onDrawToday(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List)
/**
* 绘制当前月或周的日期
@@ -34,12 +27,12 @@ public interface CalendarPainter {
* @param canvas 画布
* @param rectF 日期的位置矩形
* @param localDate 月日历-> 当前页面月份中的每个日期(内部是循环处理)
- * 周日历-> 当前页面一周中的每个日期(内部是循环处理)
+ * 周日历-> 当前页面一周中的每个日期(内部是循环处理)
* @param checkedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
+ * 单选模式中,集合中最多只有一个元素,
+ * 多选模式中,可以有多个元素
*/
- void onDrawCurrentMonthOrWeek(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList);
+ fun onDrawCurrentMonthOrWeek(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List)
/**
* 绘制上一月,下一月的日期,周日历不用实现
@@ -47,12 +40,12 @@ public interface CalendarPainter {
* @param canvas 画布
* @param rectF 日期的位置矩形
* @param localDate 月日历-> 当前页面上一月、下一月中的每个日期(内部是循环处理)
- * 周日历-> 周日历无需实现此方法
+ * 周日历-> 周日历无需实现此方法
* @param checkedDateList 所有选中日期的集合,
- * 单选模式中,集合中最多只有一个元素,
- * 多选模式中,可以有多个元素
+ * 单选模式中,集合中最多只有一个元素,
+ * 多选模式中,可以有多个元素
*/
- void onDrawLastOrNextMonth(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList);
+ fun onDrawLastOrNextMonth(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List)
/**
* 绘制不可用的日期,和方法setDateInterval(startFormatDate, endFormatDate)对应,
@@ -62,9 +55,5 @@ public interface CalendarPainter {
* @param rectF 日期的位置矩形
* @param localDate 不可用的日期
*/
- default void onDrawDisableDate(Canvas canvas, RectF rectF, LocalDate localDate) {
-
- }
-
-
-}
+ fun onDrawDisableDate(canvas: Canvas, rectF: RectF, localDate: LocalDate) {}
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/painter/InnerPainter.java b/ncalendar/src/main/java/com/necer/painter/InnerPainter.java
deleted file mode 100644
index 82df5664..00000000
--- a/ncalendar/src/main/java/com/necer/painter/InnerPainter.java
+++ /dev/null
@@ -1,399 +0,0 @@
-package com.necer.painter;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-
-import androidx.core.content.ContextCompat;
-
-import com.necer.R;
-import com.necer.calendar.ICalendar;
-import com.necer.entity.CalendarDate;
-import com.necer.utils.Attrs;
-import com.necer.utils.CalendarUtil;
-import com.necer.utils.DrawableUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author necer
- * @date 2019/1/3
- */
-public class InnerPainter implements CalendarPainter {
-
- private Attrs mAttrs;
- private Paint mTextPaint;
-
- private int noAlphaColor = 255;
-
- private List mHolidayList;
- private List mWorkdayList;
-
- private List mPointList;
- private Map mReplaceLunarStrMap;
- private Map mReplaceLunarColorMap;
- private Map mStretchStrMap;
-
- private ICalendar mCalendar;
-
- private Drawable mDefaultCheckedBackground;
- private Drawable mTodayCheckedBackground;
-
- private Drawable mDefaultCheckedPoint;
- private Drawable mDefaultUnCheckedPoint;
- private Drawable mTodayCheckedPoint;
- private Drawable mTodayUnCheckedPoint;
-
-
- private Context mContext;
-
-
- public InnerPainter(Context context, ICalendar calendar) {
- this.mAttrs = calendar.getAttrs();
- this.mContext = context;
- this.mCalendar = calendar;
-
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setTextAlign(Paint.Align.CENTER);
-
- mPointList = new ArrayList<>();
- mHolidayList = new ArrayList<>();
- mWorkdayList = new ArrayList<>();
- mReplaceLunarStrMap = new HashMap<>();
- mReplaceLunarColorMap = new HashMap<>();
- mStretchStrMap = new HashMap<>();
-
- mDefaultCheckedBackground = ContextCompat.getDrawable(context, mAttrs.defaultCheckedBackground);
- mTodayCheckedBackground = ContextCompat.getDrawable(context, mAttrs.todayCheckedBackground);
-
- mDefaultCheckedPoint = ContextCompat.getDrawable(context, mAttrs.defaultCheckedPoint);
- mDefaultUnCheckedPoint = ContextCompat.getDrawable(context, mAttrs.defaultUnCheckedPoint);
- mTodayCheckedPoint = ContextCompat.getDrawable(context, mAttrs.todayCheckedPoint);
- mTodayUnCheckedPoint = ContextCompat.getDrawable(context, mAttrs.todayUnCheckedPoint);
-
- List holidayList = CalendarUtil.getHolidayList();
- for (int i = 0; i < holidayList.size(); i++) {
- mHolidayList.add(new LocalDate(holidayList.get(i)));
- }
- List workdayList = CalendarUtil.getWorkdayList();
- for (int i = 0; i < workdayList.size(); i++) {
- mWorkdayList.add(new LocalDate(workdayList.get(i)));
- }
- }
-
-
- @Override
- public void onDrawToday(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList) {
- if (checkedDateList.contains(localDate)) {
- drawCheckedBackground(canvas, mTodayCheckedBackground, rectF, noAlphaColor);
- drawSolar(canvas, rectF, localDate, mAttrs.todayCheckedSolarTextColor, noAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.todayCheckedLunarTextColor, noAlphaColor);
- drawPoint(canvas, rectF, localDate, mTodayCheckedPoint, noAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.todayCheckedHoliday, mAttrs.todayCheckedWorkday, mAttrs.todayCheckedHolidayTextColor, mAttrs.todayCheckedWorkdayTextColor, noAlphaColor);
- } else {
- drawSolar(canvas, rectF, localDate, mAttrs.todayUnCheckedSolarTextColor, noAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.todayUnCheckedLunarTextColor, noAlphaColor);
- drawPoint(canvas, rectF, localDate, mTodayUnCheckedPoint, noAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.todayUnCheckedHoliday, mAttrs.todayUnCheckedWorkday, mAttrs.todayUnCheckedHolidayTextColor, mAttrs.todayUnCheckedWorkdayTextColor, noAlphaColor);
- }
- drawStretchText(canvas, rectF, noAlphaColor, localDate);
- }
-
- @Override
- public void onDrawCurrentMonthOrWeek(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList) {
- if (checkedDateList.contains(localDate)) {
- drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, noAlphaColor);
- drawSolar(canvas, rectF, localDate, mAttrs.defaultCheckedSolarTextColor, noAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.defaultCheckedLunarTextColor, noAlphaColor);
- drawPoint(canvas, rectF, localDate, mDefaultCheckedPoint, noAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.defaultCheckedHoliday, mAttrs.defaultCheckedWorkday, mAttrs.defaultCheckedHolidayTextColor, mAttrs.defaultCheckedWorkdayTextColor, noAlphaColor);
-
- } else {
- drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, noAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, noAlphaColor);
- drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, noAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.defaultUnCheckedHoliday, mAttrs.defaultUnCheckedWorkday, mAttrs.defaultUnCheckedHolidayTextColor, mAttrs.defaultUnCheckedWorkdayTextColor, noAlphaColor);
- }
- drawStretchText(canvas, rectF, noAlphaColor, localDate);
-
- }
-
- @Override
- public void onDrawLastOrNextMonth(Canvas canvas, RectF rectF, LocalDate localDate, List checkedDateList) {
- if (checkedDateList.contains(localDate)) {
- drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, mAttrs.lastNextMothAlphaColor);
- drawSolar(canvas, rectF, localDate, mAttrs.defaultCheckedSolarTextColor, mAttrs.lastNextMothAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.defaultCheckedLunarTextColor, mAttrs.lastNextMothAlphaColor);
- drawPoint(canvas, rectF, localDate, mDefaultCheckedPoint, mAttrs.lastNextMothAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.defaultCheckedHoliday, mAttrs.defaultCheckedWorkday, mAttrs.defaultCheckedHolidayTextColor, mAttrs.defaultCheckedWorkdayTextColor, mAttrs.lastNextMothAlphaColor);
- } else {
- drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, mAttrs.lastNextMothAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, mAttrs.lastNextMothAlphaColor);
- drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, mAttrs.lastNextMothAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.defaultUnCheckedHoliday, mAttrs.defaultUnCheckedWorkday, mAttrs.defaultUnCheckedHolidayTextColor, mAttrs.defaultUnCheckedWorkdayTextColor, mAttrs.lastNextMothAlphaColor);
- }
- drawStretchText(canvas, rectF, mAttrs.lastNextMothAlphaColor, localDate);
- }
-
- @Override
- public void onDrawDisableDate(Canvas canvas, RectF rectF, LocalDate localDate) {
- drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, mAttrs.disabledAlphaColor);
- drawLunar(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, mAttrs.disabledAlphaColor);
- drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, mAttrs.disabledAlphaColor);
- drawHolidayWorkday(canvas, rectF, localDate, mAttrs.defaultUnCheckedHoliday, mAttrs.defaultUnCheckedWorkday, mAttrs.defaultUnCheckedHolidayTextColor, mAttrs.defaultUnCheckedWorkdayTextColor, mAttrs.disabledAlphaColor);
- drawStretchText(canvas, rectF, mAttrs.disabledAlphaColor, localDate);
- }
-
- //选中背景
- private void drawCheckedBackground(Canvas canvas, Drawable drawable, RectF rectF, int alphaColor) {
- Rect drawableBounds = DrawableUtil.getDrawableBounds((int) rectF.centerX(), (int) rectF.centerY(), drawable);
- drawable.setBounds(drawableBounds);
- drawable.setAlpha(alphaColor);
- drawable.draw(canvas);
- }
-
-
- //绘制公历
- private void drawSolar(Canvas canvas, RectF rectF, LocalDate date, int color, int alphaColor) {
- mTextPaint.setColor(color);
- mTextPaint.setAlpha(alphaColor);
- mTextPaint.setTextSize(mAttrs.solarTextSize);
- mTextPaint.setFakeBoldText(mAttrs.solarTextBold);
- canvas.drawText(date.getDayOfMonth() + "", rectF.centerX(), mAttrs.showLunar ? rectF.centerY() : getTextBaseLineY(rectF.centerY()), mTextPaint);
- }
-
- //绘制农历
- private void drawLunar(Canvas canvas, RectF rectF, LocalDate localDate, int color, int alphaColor) {
- if (mAttrs.showLunar) {
- CalendarDate calendarDate = CalendarUtil.getCalendarDate(localDate);
- //农历部分文字展示优先顺序 替换的文字、农历节日、节气、公历节日、正常农历日期
- String lunarString;
- String replaceString = mReplaceLunarStrMap.get(calendarDate.localDate);
- if (!TextUtils.isEmpty(replaceString)) {
- lunarString = replaceString;
- } else if (!TextUtils.isEmpty(calendarDate.lunarHoliday)) {
- lunarString = calendarDate.lunarHoliday;
- } else if (!TextUtils.isEmpty(calendarDate.solarTerm)) {
- lunarString = calendarDate.solarTerm;
- } else if (!TextUtils.isEmpty(calendarDate.solarHoliday)) {
- lunarString = calendarDate.solarHoliday;
- } else {
- lunarString = calendarDate.lunar.lunarOnDrawStr;
- }
-
- Integer replaceColor = mReplaceLunarColorMap.get(calendarDate.localDate);
- mTextPaint.setColor(replaceColor == null ? color : replaceColor);
- mTextPaint.setTextSize(mAttrs.lunarTextSize);
- mTextPaint.setAlpha(alphaColor);
- mTextPaint.setFakeBoldText(mAttrs.lunarTextBold);
- canvas.drawText(lunarString, rectF.centerX(), rectF.centerY() + mAttrs.lunarDistance, mTextPaint);
- }
- }
-
-
- //绘制标记
- private void drawPoint(Canvas canvas, RectF rectF, LocalDate date, Drawable drawable, int alphaColor) {
- if (mPointList.contains(date)) {
- float centerY = mAttrs.pointLocation == Attrs.DOWN ? (rectF.centerY() + mAttrs.pointDistance) : (rectF.centerY() - mAttrs.pointDistance);
- Rect drawableBounds = DrawableUtil.getDrawableBounds((int) rectF.centerX(), (int) centerY, drawable);
- drawable.setBounds(drawableBounds);
- drawable.setAlpha(alphaColor);
- drawable.draw(canvas);
- }
- }
-
- //绘制节假日
- private void drawHolidayWorkday(Canvas canvas, RectF rectF, LocalDate localDate, Drawable holidayDrawable, Drawable workdayDrawable, int holidayTextColor, int workdayTextColor, int alphaColor) {
- if (mAttrs.showHolidayWorkday) {
- int[] holidayLocation = getHolidayWorkdayLocation(rectF.centerX(), rectF.centerY());
- if (mHolidayList.contains(localDate)) {
- if (holidayDrawable == null) {
- mTextPaint.setTextSize(mAttrs.holidayWorkdayTextSize);
- mTextPaint.setColor(holidayTextColor);
- canvas.drawText(TextUtils.isEmpty(mAttrs.holidayText) ? mContext.getString(R.string.N_holidayText) : mAttrs.holidayText, holidayLocation[0], getTextBaseLineY(holidayLocation[1]), mTextPaint);
- } else {
- Rect drawableBounds = DrawableUtil.getDrawableBounds(holidayLocation[0], holidayLocation[1], holidayDrawable);
- holidayDrawable.setBounds(drawableBounds);
- holidayDrawable.setAlpha(alphaColor);
- holidayDrawable.draw(canvas);
- }
- } else if (mWorkdayList.contains(localDate)) {
- if (workdayDrawable == null) {
- mTextPaint.setTextSize(mAttrs.holidayWorkdayTextSize);
- mTextPaint.setColor(workdayTextColor);
- mTextPaint.setFakeBoldText(mAttrs.holidayWorkdayTextBold);
- canvas.drawText(TextUtils.isEmpty(mAttrs.workdayText) ? mContext.getString(R.string.N_workdayText) : mAttrs.workdayText, holidayLocation[0], getTextBaseLineY(holidayLocation[1]), mTextPaint);
- } else {
- Rect drawableBounds = DrawableUtil.getDrawableBounds(holidayLocation[0], holidayLocation[1], workdayDrawable);
- workdayDrawable.setBounds(drawableBounds);
- workdayDrawable.setAlpha(alphaColor);
- workdayDrawable.draw(canvas);
- }
- }
- }
- }
-
- //绘制拉伸的文字
- private void drawStretchText(Canvas canvas, RectF rectF, int alphaColor, LocalDate localDate) {
- float v = rectF.centerY() + mAttrs.stretchTextDistance;
- //超出当前矩形 不绘制
- if (v <= rectF.bottom) {
- String stretchText = mStretchStrMap.get(localDate);
- if (!TextUtils.isEmpty(stretchText)) {
- mTextPaint.setTextSize(mAttrs.stretchTextSize);
- mTextPaint.setColor(mAttrs.stretchTextColor);
- mTextPaint.setAlpha(alphaColor);
- mTextPaint.setFakeBoldText(mAttrs.stretchTextBold);
- canvas.drawText(stretchText, rectF.centerX(), rectF.centerY() + mAttrs.stretchTextDistance, mTextPaint);
- }
- }
- }
-
- //canvas.drawText的基准线
- private float getTextBaseLineY(float centerY) {
- Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
- return centerY - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top;
- }
-
-
- //HolidayWorkday的位置
- private int[] getHolidayWorkdayLocation(float centerX, float centerY) {
- int[] location = new int[2];
- switch (mAttrs.holidayWorkdayLocation) {
- case Attrs.TOP_LEFT:
- location[0] = (int) (centerX - mAttrs.holidayWorkdayDistance);
- location[1] = (int) (centerY - mAttrs.holidayWorkdayDistance / 2);
- break;
- case Attrs.BOTTOM_RIGHT:
- location[0] = (int) (centerX + mAttrs.holidayWorkdayDistance);
- location[1] = (int) (centerY + mAttrs.holidayWorkdayDistance / 2);
- break;
- case Attrs.BOTTOM_LEFT:
- location[0] = (int) (centerX - mAttrs.holidayWorkdayDistance);
- location[1] = (int) (centerY + mAttrs.holidayWorkdayDistance / 2);
- break;
- case Attrs.TOP_RIGHT:
- default:
- location[0] = (int) (centerX + mAttrs.holidayWorkdayDistance);
- location[1] = (int) (centerY - mAttrs.holidayWorkdayDistance / 2);
- break;
- }
- return location;
-
- }
-
- //设置标记
- public void setPointList(List list) {
- mPointList.clear();
- for (int i = 0; i < list.size(); i++) {
- LocalDate localDate = null;
- try {
- localDate = new LocalDate(list.get(i));
- } catch (Exception e) {
- throw new RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期");
- }
- mPointList.add(localDate);
- }
- mCalendar.notifyCalendar();
- }
-
- public void addPointList(List list) {
- for (int i = 0; i < list.size(); i++) {
- LocalDate localDate = null;
- try {
- localDate = new LocalDate(list.get(i));
- } catch (Exception e) {
- throw new RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期");
- }
- if (!mPointList.contains(localDate)) {
- mPointList.add(localDate);
- }
- }
- mCalendar.notifyCalendar();
- }
-
- //设置替换农历的文字
- public void setReplaceLunarStrMap(Map replaceLunarStrMap) {
- mReplaceLunarStrMap.clear();
- for (String key : replaceLunarStrMap.keySet()) {
- LocalDate localDate;
- try {
- localDate = new LocalDate(key);
- } catch (Exception e) {
- throw new RuntimeException("setReplaceLunarStrMap的参数需要 yyyy-MM-dd 格式的日期");
- }
- mReplaceLunarStrMap.put(localDate, replaceLunarStrMap.get(key));
- }
- mCalendar.notifyCalendar();
- }
-
- //设置替换农历的颜色
- public void setReplaceLunarColorMap(Map replaceLunarColorMap) {
- mReplaceLunarColorMap.clear();
- for (String key : replaceLunarColorMap.keySet()) {
- LocalDate localDate;
- try {
- localDate = new LocalDate(key);
- } catch (Exception e) {
- throw new RuntimeException("setReplaceLunarColorMap的参数需要 yyyy-MM-dd 格式的日期");
- }
- mReplaceLunarColorMap.put(localDate, replaceLunarColorMap.get(key));
- }
- mCalendar.notifyCalendar();
- }
-
-
- //设置法定节假日和补班
- public void setLegalHolidayList(List holidayList, List workdayList) {
- mHolidayList.clear();
- mWorkdayList.clear();
-
- for (int i = 0; i < holidayList.size(); i++) {
- LocalDate holidayLocalDate;
- try {
- holidayLocalDate = new LocalDate(holidayList.get(i));
- } catch (Exception e) {
- throw new RuntimeException("setLegalHolidayList集合中的参数需要 yyyy-MM-dd 格式的日期");
- }
- mHolidayList.add(holidayLocalDate);
- }
-
- for (int i = 0; i < workdayList.size(); i++) {
- LocalDate workdayLocalDate;
- try {
- workdayLocalDate = new LocalDate(workdayList.get(i));
- } catch (Exception e) {
- throw new RuntimeException("setLegalHolidayList集合中的参数需要 yyyy-MM-dd 格式的日期");
- }
- mWorkdayList.add(workdayLocalDate);
- }
- mCalendar.notifyCalendar();
- }
-
-
- public void setStretchStrMap(Map stretchStrMap) {
- mStretchStrMap.clear();
- for (String key : stretchStrMap.keySet()) {
- LocalDate localDate;
- try {
- localDate = new LocalDate(key);
-
- } catch (Exception e) {
- throw new RuntimeException("setStretchStrMap的参数需要 yyyy-MM-dd 格式的日期");
- }
- mStretchStrMap.put(localDate, stretchStrMap.get(key));
- }
- mCalendar.notifyCalendar();
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/painter/InnerPainter.kt b/ncalendar/src/main/java/com/necer/painter/InnerPainter.kt
new file mode 100644
index 00000000..b10dcda2
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/painter/InnerPainter.kt
@@ -0,0 +1,432 @@
+package com.necer.painter
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.text.TextUtils
+import androidx.core.content.ContextCompat
+import com.necer.calendar.ICalendar
+import com.necer.R
+import com.necer.utils.NAttrs
+import com.necer.utils.hutool.ChineseDate
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+/**
+ * @author necer
+ * @date 2019/1/3
+ */
+class InnerPainter(private val mContext: Context, val iCalendar: ICalendar) : CalendarPainter {
+ private val mTextPaint: Paint = Paint()
+ private val noAlphaColor = 255
+ private val mHolidayList: MutableList
+ private val mWorkdayList: MutableList
+ private val mPointList: MutableList
+ private val mReplaceLunarStrMap: MutableMap
+ private val mReplaceLunarColorMap: MutableMap
+ private val mStretchStrMap: MutableMap
+ private val mDefaultCheckedBackground: Drawable?
+ private val mTodayCheckedBackground: Drawable?
+ private val mDefaultCheckedPoint: Drawable?
+ private val mDefaultUnCheckedPoint: Drawable?
+ private val mTodayCheckedPoint: Drawable?
+ private val mTodayUnCheckedPoint: Drawable?
+ private val mDateFormatter:DateTimeFormatter =DateTimeFormatter.ofPattern("yyyy-M-d")
+
+ init {
+ mTextPaint.isAntiAlias = true
+ mTextPaint.textAlign = Paint.Align.CENTER
+ mPointList = ArrayList()
+ mHolidayList = ArrayList()
+ mWorkdayList = ArrayList()
+ mReplaceLunarStrMap = HashMap()
+ mReplaceLunarColorMap = HashMap()
+ mStretchStrMap = HashMap()
+ mDefaultCheckedBackground = ContextCompat.getDrawable(mContext, NAttrs.defaultCheckedBackground)
+ mTodayCheckedBackground = ContextCompat.getDrawable(mContext, NAttrs.todayCheckedBackground)
+ mDefaultCheckedPoint = ContextCompat.getDrawable(mContext, NAttrs.defaultCheckedPoint)
+ mDefaultUnCheckedPoint = ContextCompat.getDrawable(mContext, NAttrs.defaultUnCheckedPoint)
+ mTodayCheckedPoint = ContextCompat.getDrawable(mContext, NAttrs.todayCheckedPoint)
+ mTodayUnCheckedPoint = ContextCompat.getDrawable(mContext, NAttrs.todayUnCheckedPoint)
+ }
+
+ override fun onDrawToday(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List) {
+ if (checkedDateList.contains(localDate)) {
+ drawCheckedBackground(canvas, mTodayCheckedBackground, rectF, noAlphaColor)
+ drawSolar(canvas, rectF, localDate, NAttrs.todayCheckedSolarTextColor, noAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.todayCheckedLunarTextColor, noAlphaColor)
+ drawPoint(canvas, rectF, localDate, mTodayCheckedPoint, noAlphaColor)
+ drawHolidayWorkday(canvas, rectF, localDate, NAttrs.todayCheckedHoliday, NAttrs.todayCheckedWorkday, NAttrs.todayCheckedHolidayTextColor, NAttrs.todayCheckedWorkdayTextColor, noAlphaColor)
+ } else {
+ drawSolar(canvas, rectF, localDate, NAttrs.todayUnCheckedSolarTextColor, noAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.todayUnCheckedLunarTextColor, noAlphaColor)
+ drawPoint(canvas, rectF, localDate, mTodayUnCheckedPoint, noAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.todayUnCheckedHoliday,
+ NAttrs.todayUnCheckedWorkday,
+ NAttrs.todayUnCheckedHolidayTextColor,
+ NAttrs.todayUnCheckedWorkdayTextColor,
+ noAlphaColor
+ )
+ }
+ drawStretchText(canvas, rectF, noAlphaColor, localDate)
+ }
+
+ override fun onDrawCurrentMonthOrWeek(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List) {
+ if (checkedDateList.contains(localDate)) {
+ drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, noAlphaColor)
+ drawSolar(canvas, rectF, localDate, NAttrs.defaultCheckedSolarTextColor, noAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.defaultCheckedLunarTextColor, noAlphaColor)
+ drawPoint(canvas, rectF, localDate, mDefaultCheckedPoint, noAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.defaultCheckedHoliday,
+ NAttrs.defaultCheckedWorkday,
+ NAttrs.defaultCheckedHolidayTextColor,
+ NAttrs.defaultCheckedWorkdayTextColor,
+ noAlphaColor
+ )
+ } else {
+ drawSolar(canvas, rectF, localDate, NAttrs.defaultUnCheckedSolarTextColor, noAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.defaultUnCheckedLunarTextColor, noAlphaColor)
+ drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, noAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.defaultUnCheckedHoliday,
+ NAttrs.defaultUnCheckedWorkday,
+ NAttrs.defaultUnCheckedHolidayTextColor,
+ NAttrs.defaultUnCheckedWorkdayTextColor,
+ noAlphaColor
+ )
+ }
+ drawStretchText(canvas, rectF, noAlphaColor, localDate)
+ }
+
+ override fun onDrawLastOrNextMonth(canvas: Canvas, rectF: RectF, localDate: LocalDate, checkedDateList: List) {
+ if (checkedDateList.contains(localDate)) {
+ drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, NAttrs.lastNextMothAlphaColor)
+ drawSolar(canvas, rectF, localDate, NAttrs.defaultCheckedSolarTextColor, NAttrs.lastNextMothAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.defaultCheckedLunarTextColor, NAttrs.lastNextMothAlphaColor)
+ drawPoint(canvas, rectF, localDate, mDefaultCheckedPoint, NAttrs.lastNextMothAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.defaultCheckedHoliday,
+ NAttrs.defaultCheckedWorkday,
+ NAttrs.defaultCheckedHolidayTextColor,
+ NAttrs.defaultCheckedWorkdayTextColor,
+ NAttrs.lastNextMothAlphaColor
+ )
+ } else {
+ drawSolar(canvas, rectF, localDate, NAttrs.defaultUnCheckedSolarTextColor, NAttrs.lastNextMothAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.defaultUnCheckedLunarTextColor, NAttrs.lastNextMothAlphaColor)
+ drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, NAttrs.lastNextMothAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.defaultUnCheckedHoliday,
+ NAttrs.defaultUnCheckedWorkday,
+ NAttrs.defaultUnCheckedHolidayTextColor,
+ NAttrs.defaultUnCheckedWorkdayTextColor,
+ NAttrs.lastNextMothAlphaColor
+ )
+ }
+ drawStretchText(canvas, rectF, NAttrs.lastNextMothAlphaColor, localDate)
+ }
+
+ override fun onDrawDisableDate(canvas: Canvas, rectF: RectF, localDate: LocalDate) {
+ drawSolar(canvas, rectF, localDate, NAttrs.defaultUnCheckedSolarTextColor, NAttrs.disabledAlphaColor)
+ drawLunar(canvas, rectF, localDate, NAttrs.defaultUnCheckedLunarTextColor, NAttrs.disabledAlphaColor)
+ drawPoint(canvas, rectF, localDate, mDefaultUnCheckedPoint, NAttrs.disabledAlphaColor)
+ drawHolidayWorkday(
+ canvas,
+ rectF,
+ localDate,
+ NAttrs.defaultUnCheckedHoliday,
+ NAttrs.defaultUnCheckedWorkday,
+ NAttrs.defaultUnCheckedHolidayTextColor,
+ NAttrs.defaultUnCheckedWorkdayTextColor,
+ NAttrs.disabledAlphaColor
+ )
+ drawStretchText(canvas, rectF, NAttrs.disabledAlphaColor, localDate)
+ }
+
+ //选中背景
+ private fun drawCheckedBackground(canvas: Canvas?, drawable: Drawable?, rectF: RectF?, alphaColor: Int) {
+ val drawableBounds: Rect = getDrawableBounds(rectF!!.centerX().toInt(), rectF.centerY().toInt(), drawable)
+ drawable!!.bounds = drawableBounds
+ drawable.alpha = alphaColor
+ drawable.draw(canvas!!)
+ }
+
+ //绘制公历
+ private fun drawSolar(canvas: Canvas?, rectF: RectF?, date: LocalDate?, color: Int, alphaColor: Int) {
+ mTextPaint.color = color
+ mTextPaint.alpha = alphaColor
+ mTextPaint.textSize = NAttrs.solarTextSize
+ mTextPaint.isFakeBoldText = NAttrs.solarTextBold
+ canvas!!.drawText(date!!.dayOfMonth.toString() + "", rectF!!.centerX(), if (NAttrs.showLunar) rectF.centerY() else getTextBaseLineY(rectF.centerY()), mTextPaint)
+ }
+
+ //绘制农历
+ private fun drawLunar(canvas: Canvas?, rectF: RectF?, localDate: LocalDate, color: Int, alphaColor: Int) {
+ if (NAttrs.showLunar) {
+ val chineseDate = ChineseDate(localDate)
+ //农历部分文字展示优先顺序 替换的文字、农历节日、节气、公历节日、正常农历日期
+ val lunarString: String
+ val replaceString = mReplaceLunarStrMap[localDate]
+ lunarString = if (!TextUtils.isEmpty(replaceString)) {
+ replaceString!!
+ } else if (!TextUtils.isEmpty(chineseDate.getLunarFestivals())) {
+ chineseDate.getLunarFestivals()!!
+ } else if (!TextUtils.isEmpty(chineseDate.getTerm())) {
+ chineseDate.getTerm()
+ } else if (!TextUtils.isEmpty(chineseDate.getSolarFestivals())) {
+ chineseDate.getSolarFestivals()!!
+ } else {
+ var chineseText = chineseDate.getChineseDay()
+ if (chineseText == "初一") {
+ chineseText = chineseDate.getChineseMonthName()
+ }
+ chineseText
+ }
+ val replaceColor = mReplaceLunarColorMap[localDate]
+ mTextPaint.color = replaceColor ?: color
+ mTextPaint.textSize = NAttrs.lunarTextSize
+ mTextPaint.alpha = alphaColor
+ mTextPaint.isFakeBoldText = NAttrs.lunarTextBold
+ canvas!!.drawText(lunarString, rectF!!.centerX(), rectF.centerY() + NAttrs.lunarDistance, mTextPaint)
+ }
+ }
+
+ //绘制标记
+ private fun drawPoint(canvas: Canvas?, rectF: RectF?, date: LocalDate?, drawable: Drawable?, alphaColor: Int) {
+ if (mPointList.contains(date)) {
+ val centerY = if (NAttrs.pointLocation == NAttrs.DOWN) rectF!!.centerY() + NAttrs.pointDistance else rectF!!.centerY() - NAttrs.pointDistance
+ val drawableBounds: Rect = getDrawableBounds(rectF.centerX().toInt(), centerY.toInt(), drawable)
+ drawable!!.bounds = drawableBounds
+ drawable.alpha = alphaColor
+ drawable.draw(canvas!!)
+ }
+ }
+
+ //绘制节假日
+ private fun drawHolidayWorkday(
+ canvas: Canvas,
+ rectF: RectF,
+ localDate: LocalDate,
+ holidayDrawable: Drawable?,
+ workdayDrawable: Drawable?,
+ holidayTextColor: Int,
+ workdayTextColor: Int,
+ alphaColor: Int
+ ) {
+ if (NAttrs.showHolidayWorkday) {
+ val holidayLocation = getHolidayWorkdayLocation(rectF.centerX(), rectF.centerY())
+ if (mHolidayList.contains(localDate)) {
+ if (holidayDrawable == null) {
+ mTextPaint.textSize = NAttrs.holidayWorkdayTextSize
+ mTextPaint.color = holidayTextColor
+ mTextPaint.alpha = alphaColor
+ canvas.drawText(
+ if (TextUtils.isEmpty(NAttrs.holidayText)) mContext.getString(R.string.N_holidayText) else NAttrs.holidayText!!, holidayLocation[0].toFloat(), getTextBaseLineY(
+ holidayLocation[1].toFloat()
+ ), mTextPaint
+ )
+ } else {
+ val drawableBounds: Rect = getDrawableBounds(holidayLocation[0], holidayLocation[1], holidayDrawable)
+ holidayDrawable.bounds = drawableBounds
+ holidayDrawable.alpha = alphaColor
+ holidayDrawable.draw(canvas)
+ }
+ } else if (mWorkdayList.contains(localDate)) {
+ if (workdayDrawable == null) {
+ mTextPaint.textSize = NAttrs.holidayWorkdayTextSize
+ mTextPaint.color = workdayTextColor
+ mTextPaint.alpha = alphaColor
+ mTextPaint.isFakeBoldText = NAttrs.holidayWorkdayTextBold
+ canvas.drawText(
+ if (TextUtils.isEmpty(NAttrs.workdayText)) mContext.getString(R.string.N_workdayText) else NAttrs.workdayText!!, holidayLocation[0].toFloat(), getTextBaseLineY(
+ holidayLocation[1].toFloat()
+ ), mTextPaint
+ )
+ } else {
+ val drawableBounds: Rect = getDrawableBounds(holidayLocation[0], holidayLocation[1], workdayDrawable)
+ workdayDrawable.bounds = drawableBounds
+ workdayDrawable.alpha = alphaColor
+ workdayDrawable.draw(canvas)
+ }
+ }
+ }
+ }
+
+ //绘制拉伸的文字
+ private fun drawStretchText(canvas: Canvas?, rectF: RectF?, alphaColor: Int, localDate: LocalDate?) {
+
+ val v = rectF!!.centerY() + NAttrs.stretchTextDistance
+ //超出当前矩形 不绘制
+ if (v <= rectF.bottom) {
+ val stretchText = mStretchStrMap[localDate]
+ if (!TextUtils.isEmpty(stretchText)) {
+ mTextPaint.textSize = NAttrs.stretchTextSize
+ mTextPaint.color = NAttrs.stretchTextColor
+ mTextPaint.alpha = alphaColor
+ mTextPaint.isFakeBoldText = NAttrs.stretchTextBold
+ canvas!!.drawText(stretchText!!, rectF.centerX(), rectF.centerY() + NAttrs.stretchTextDistance, mTextPaint)
+ }
+ }
+ }
+
+ //canvas.drawText的基准线
+ private fun getTextBaseLineY(centerY: Float): Float {
+ val fontMetrics = mTextPaint.fontMetrics
+ return centerY - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top
+ }
+
+ //HolidayWorkday的位置
+ private fun getHolidayWorkdayLocation(centerX: Float, centerY: Float): IntArray {
+ val location = IntArray(2)
+ when (NAttrs.holidayWorkdayLocation) {
+ NAttrs.TOP_LEFT -> {
+ location[0] = (centerX - NAttrs.holidayWorkdayDistance).toInt()
+ location[1] = (centerY - NAttrs.holidayWorkdayDistance / 2).toInt()
+ }
+ NAttrs.BOTTOM_RIGHT -> {
+ location[0] = (centerX + NAttrs.holidayWorkdayDistance).toInt()
+ location[1] = (centerY + NAttrs.holidayWorkdayDistance / 2).toInt()
+ }
+ NAttrs.BOTTOM_LEFT -> {
+ location[0] = (centerX - NAttrs.holidayWorkdayDistance).toInt()
+ location[1] = (centerY + NAttrs.holidayWorkdayDistance / 2).toInt()
+ }
+ NAttrs.TOP_RIGHT -> {
+ location[0] = (centerX + NAttrs.holidayWorkdayDistance).toInt()
+ location[1] = (centerY - NAttrs.holidayWorkdayDistance / 2).toInt()
+ }
+ else -> {
+ location[0] = (centerX + NAttrs.holidayWorkdayDistance).toInt()
+ location[1] = (centerY - NAttrs.holidayWorkdayDistance / 2).toInt()
+ }
+ }
+ return location
+ }
+
+ //设置标记
+ fun setPointList(list: List) {
+ mPointList.clear()
+ for (i in list.indices) {
+ var localDate: LocalDate? = null
+ localDate = try {
+ LocalDate.parse(list[i],mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mPointList.add(localDate)
+ }
+ iCalendar.notifyCalendar()
+ }
+
+ fun addPointList(list: List) {
+ for (i in list.indices) {
+ var localDate: LocalDate? = null
+ localDate = try {
+ LocalDate.parse(list[i],mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ if (!mPointList.contains(localDate)) {
+ mPointList.add(localDate)
+ }
+ }
+ iCalendar.notifyCalendar()
+ }
+
+ //设置替换农历的文字
+ fun setReplaceLunarStrMap(replaceLunarStrMap: Map) {
+ mReplaceLunarStrMap.clear()
+ for (key in replaceLunarStrMap.keys) {
+ val localDate: LocalDate = try {
+ LocalDate.parse(key,mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setReplaceLunarStrMap的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mReplaceLunarStrMap[localDate] = replaceLunarStrMap[key]
+ }
+ iCalendar.notifyCalendar()
+ }
+
+ //设置替换农历的颜色
+ fun setReplaceLunarColorMap(replaceLunarColorMap: Map) {
+ mReplaceLunarColorMap.clear()
+ for (key in replaceLunarColorMap.keys) {
+ val localDate: LocalDate = try {
+ LocalDate.parse(key,mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setReplaceLunarColorMap的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mReplaceLunarColorMap[localDate] = replaceLunarColorMap[key]
+ }
+ iCalendar.notifyCalendar()
+ }
+
+ //设置法定节假日和补班
+ fun setLegalHolidayList(holidayList: List, workdayList: List) {
+ mHolidayList.clear()
+ mWorkdayList.clear()
+ for (i in holidayList.indices) {
+ val holidayLocalDate: LocalDate = try {
+ LocalDate.parse(holidayList[i],mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setLegalHolidayList集合中的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mHolidayList.add(holidayLocalDate)
+ }
+ for (i in workdayList.indices) {
+ val workdayLocalDate: LocalDate = try {
+ LocalDate.parse(workdayList[i],mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setLegalHolidayList集合中的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mWorkdayList.add(workdayLocalDate)
+ }
+ iCalendar.notifyCalendar()
+ }
+
+ fun setStretchStrMap(stretchStrMap: Map) {
+ mStretchStrMap.clear()
+ for (key in stretchStrMap.keys) {
+ val localDate: LocalDate = try {
+ LocalDate.parse(key,mDateFormatter)
+ } catch (e: Exception) {
+ throw RuntimeException("setStretchStrMap的参数需要 yyyy-MM-dd 格式的日期")
+ }
+ mStretchStrMap[localDate] = stretchStrMap[key]
+ }
+ iCalendar.notifyCalendar()
+ }
+
+
+ private fun getDrawableBounds(centerX: Int, centerY: Int, drawable: Drawable?): Rect {
+ if (drawable == null) {
+ return Rect()
+ }
+ return Rect(
+ centerX - drawable.intrinsicWidth / 2,
+ centerY - drawable.intrinsicHeight / 2,
+ centerX + drawable.intrinsicWidth / 2,
+ centerY + drawable.intrinsicHeight / 2
+ )
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/painter/NumBackground.java b/ncalendar/src/main/java/com/necer/painter/NumBackground.java
deleted file mode 100644
index 86f000ab..00000000
--- a/ncalendar/src/main/java/com/necer/painter/NumBackground.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.necer.painter;
-
-import android.graphics.Canvas;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.Drawable;
-
-import com.necer.drawable.TextDrawable;
-
-import org.joda.time.LocalDate;
-
-/**
- * Created by necer on 2020/3/27.
- */
-public class NumBackground implements CalendarBackground {
-
-
- private TextDrawable mTextDrawable;
- private int mAlphaColor;
-
- public NumBackground(float textSize, int color, int alphaColor) {
- this.mAlphaColor = alphaColor;
- mTextDrawable = new TextDrawable(textSize);
- mTextDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
- }
-
- @Override
- public Drawable getBackgroundDrawable(LocalDate localDate, int currentDistance, int totalDistance) {
- int alphaColor = mAlphaColor * currentDistance / totalDistance;
- mTextDrawable.setAlpha(alphaColor);
- mTextDrawable.setText(String.valueOf(localDate.getMonthOfYear()));
- return mTextDrawable;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/painter/WhiteBackground.java b/ncalendar/src/main/java/com/necer/painter/WhiteBackground.java
deleted file mode 100644
index e3fe142a..00000000
--- a/ncalendar/src/main/java/com/necer/painter/WhiteBackground.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.necer.painter;
-
-import android.annotation.SuppressLint;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-
-import org.joda.time.LocalDate;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Created by necer on 2020/3/27.
- */
-public class WhiteBackground implements CalendarBackground {
-
-
- @Override
- public Drawable getBackgroundDrawable(LocalDate localDate, int totalDistance, int currentDistance) {
- return new Drawable() {
- @Override
- public void draw(@NonNull Canvas canvas) {
- canvas.drawColor(Color.WHITE);
- }
-
- @Override
- public void setAlpha(int alpha) {
-
- }
-
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
-
- }
-
- @SuppressLint("WrongConstant")
- @Override
- public int getOpacity() {
- return 0;
- }
- };
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/Attrs.java b/ncalendar/src/main/java/com/necer/utils/Attrs.java
deleted file mode 100644
index 35730e4b..00000000
--- a/ncalendar/src/main/java/com/necer/utils/Attrs.java
+++ /dev/null
@@ -1,398 +0,0 @@
-package com.necer.utils;
-
-import android.graphics.drawable.Drawable;
-
-/**
- * @author necer
- * @date 2017/6/13
- */
-
-public class Attrs {
-
-
- /**
- * 今天选中的背景 shape
- */
- public int todayCheckedBackground;
- /**
- * 其他日期选中的背景 shape
- */
- public int defaultCheckedBackground;
-
-
- /**
- * 指示圆点的位置
- * 在公历日期上面
- */
- public static final int UP = 200;
- /**
- * 指示圆点的位置
- * 在公历日期下面
- */
- public static final int DOWN = 201;
-
- /**
- * 周的第一天
- * 周日
- */
- public static final int SUNDAY = 300;
- /**
- * 周的第一天
- * 周一
- */
- public static final int MONDAY = 301;
-
-
- /**
- * 节假日的位置
- * 右上方
- */
- public static final int TOP_RIGHT = 400;
- /**
- * 节假日的位置
- * 左上方
- */
- public static final int TOP_LEFT = 401;
- /**
- * 节假日的位置
- * 右下方
- */
- public static final int BOTTOM_RIGHT = 402;
- /**
- * 节假日的位置
- * 左下方
- */
- public static final int BOTTOM_LEFT = 403;
-
-
- /**
- * 公历日期属性
- * 今天选中的公历字体颜色
- */
- public int todayCheckedSolarTextColor;
- /**
- * 公历日期属性
- * 今天不选中的公历字体颜色
- */
- public int todayUnCheckedSolarTextColor;
- /**
- * 公历日期属性
- * 默认选中的公历字体颜色
- */
- public int defaultCheckedSolarTextColor;
- /**
- * 公历日期属性
- * 默认不选中公历字体颜色
- */
- public int defaultUnCheckedSolarTextColor;
- /**
- * 公历日期属性
- * 公历字体大小
- */
- public float solarTextSize;
-
- /**
- * 公历日期属性
- * 公历字体是否加粗
- */
- public boolean solarTextBold;
-
- /**
- * 标记日期属性
- * 今天选中时标记
- */
- public int todayCheckedPoint;
- /**
- * 标记日期属性
- * 今天不选中时标记
- */
- public int todayUnCheckedPoint;
- /**
- * 标记日期属性
- * 默认选中时标记
- */
- public int defaultCheckedPoint;
- /**
- * 标记日期属性
- * 默认不选中时标记
- */
- public int defaultUnCheckedPoint;
- /**
- * 标记日期属性
- * 0 在上面 1在下面
- */
- public int pointLocation;
- /**
- * 标记日期属性
- * 标记点到文字中心的距离
- */
- public float pointDistance;
-
-
- /**
- * 节假日日期属性 drawable
- * 今天选中时节假日
- */
- public Drawable todayCheckedHoliday;
- /**
- * 节假日日期属性 drawable
- * 今天不选中时节假日
- */
- public Drawable todayUnCheckedHoliday;
- /**
- * 节假日日期属性 drawable
- * 默认选中时节假日
- */
- public Drawable defaultCheckedHoliday;
- /**
- * 节假日日期属性 drawable
- * 默认不选中时节假日
- */
- public Drawable defaultUnCheckedHoliday;
- /**
- * 节假日日期属性 drawable
- * 今天选中时工作日
- */
- public Drawable todayCheckedWorkday;
- /**
- * 节假日日期属性 drawable
- * 今天不选中工作日
- */
- public Drawable todayUnCheckedWorkday;
- /**
- * 节假日日期属性 drawable
- * 默认选中时工作日
- */
- public Drawable defaultCheckedWorkday;
- /**
- * 节假日日期属性 drawable
- * 默认不选中时工作日
- */
- public Drawable defaultUnCheckedWorkday;
-
-
- /**
- * 节假日日期属性 text
- * 是否显示节假日和工作日标记
- */
- public boolean showHolidayWorkday;
- /**
- * 节假日日期属性 text
- * 节假日文字
- */
- public String holidayText;
- /**
- * 节假日日期属性 text
- * 工作日文字
- */
- public String workdayText;
- /**
- * 节假日日期属性 text
- * 字体大小
- */
- public float holidayWorkdayTextSize;
-
-
- /**
- * 节假日日期属性 text
- * 是否加粗
- */
- public boolean holidayWorkdayTextBold;
- /**
- * 节假日日期属性 text
- * 文字距离中心距离
- */
- public float holidayWorkdayDistance;
- /**
- * 节假日日期属性 text
- * 文字的位置
- */
- public int holidayWorkdayLocation;
- /**
- * 节假日日期属性 text
- * 今天选中时节假日字体颜色
- */
- public int todayCheckedHolidayTextColor;
- /**
- * 节假日日期属性 text
- * 今天未选中时节假日字体颜色
- */
- public int todayUnCheckedHolidayTextColor;
- /**
- * 节假日日期属性 text
- * 默认选中时节假日字体颜色
- */
- public int defaultCheckedHolidayTextColor;
- /**
- * 节假日日期属性 text
- * 默认未选中时节假日字体颜色
- */
- public int defaultUnCheckedHolidayTextColor;
- /**
- * 节假日日期属性 text
- * 今天选中时工作日字体颜色
- */
- public int todayCheckedWorkdayTextColor;
- /**
- * 节假日日期属性 text
- * 今天选中时工作日颜色
- */
- public int todayUnCheckedWorkdayTextColor;
- /**
- * 节假日日期属性 text
- * 默认选中时工作日字体颜色
- */
- public int defaultCheckedWorkdayTextColor;
- /**
- * 节假日日期属性 text
- * 默认选中时工作日字体颜色
- */
- public int defaultUnCheckedWorkdayTextColor;
-
-
- /**
- * 农历属性
- * 是否显示农历
- */
- public boolean showLunar;
- /**
- * 农历属性
- * 今天选中时农历颜色
- */
- public int todayCheckedLunarTextColor;
- /**
- * 农历属性
- * 今天不选中时农历颜色
- */
- public int todayUnCheckedLunarTextColor;
- /**
- * 农历属性
- * 默认选中时农历颜色
- */
- public int defaultCheckedLunarTextColor;
- /**
- * 农历属性
- * 默认不选中时农历颜色
- */
- public int defaultUnCheckedLunarTextColor;
- /**
- * 农历属性
- * 农历字体大小
- */
- public float lunarTextSize;
- /**
- * 农历属性
- * 农历字体是否加粗
- */
- public boolean lunarTextBold;
- /**
- * 农历属性
- * 农历文字到文字中心的距离
- */
- public float lunarDistance;
-
-
- /**
- * 上下月月的颜色透明度
- */
- public int lastNextMothAlphaColor;
-
-
- /**
- * 日历一周开始是周日或周一
- */
- public int firstDayOfWeek;
-
-
- /**
- * 折叠日历属性
- * 折叠日历的默认展示日历
- */
- public int defaultCalendar;
- /**
- * 折叠日历属性
- * 折叠日历月日历的高度
- */
- public int calendarHeight;
- /**
- * 折叠日历属性
- * 是否可拉伸
- */
- public boolean stretchCalendarEnable;
- /**
- * 折叠日历属性
- * 拉伸后日历的高度
- */
- public int stretchCalendarHeight;
- /**
- * 折叠日历属性
- * 折叠日历动画时间
- */
- public int animationDuration;
-
-
- /**
- * 不可用的日期颜色透明度
- */
- public int disabledAlphaColor;
- /**
- * 点击不可用的日期提示语
- */
- public String disabledString;
-
-
- /**
- * 拉伸显示的字体大小
- */
- public float stretchTextSize;
-
- /**
- * 拉伸字体加粗
- */
- public boolean stretchTextBold;
-
- /**
- * 拉伸显示的字体颜色
- */
- public int stretchTextColor;
- /**
- * 拉伸显示的字体距离矩形中心的距离
- */
- public float stretchTextDistance;
-
- /**
- * 月日历是否全部6行
- */
- public boolean allMonthSixLine;
-
-
- /**
- * 是否显示数字背景
- */
- public boolean showNumberBackground;
- /**
- * 数字背景字体大小
- */
- public float numberBackgroundTextSize;
- /**
- * 数字背景字体颜色
- */
- public int numberBackgroundTextColor;
- /**
- * 数字背景字体透明度
- */
- public int numberBackgroundAlphaColor;
-
- /**
- * 月日历上下月是否可点击
- */
- public boolean lastNextMonthClickEnable;
-
-
- /**
- * 日历背景
- */
- public Drawable calendarBackground;
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/AttrsUtil.java b/ncalendar/src/main/java/com/necer/utils/AttrsUtil.java
deleted file mode 100644
index 97d3290a..00000000
--- a/ncalendar/src/main/java/com/necer/utils/AttrsUtil.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.necer.utils;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import androidx.core.content.ContextCompat;
-
-import com.necer.R;
-import com.necer.enumeration.CalendarState;
-
-/**
- * @author necer
- * @date 2018/11/28
- */
-public class AttrsUtil {
-
-
- public static Attrs getAttrs(Context context, AttributeSet attributeSet) {
- Attrs attrs = new Attrs();
- TypedArray ta = context.obtainStyledAttributes(attributeSet, R.styleable.NCalendar);
-
- attrs.todayCheckedBackground = ta.getResourceId(R.styleable.NCalendar_todayCheckedBackground, R.drawable.n_bg_checked_today);
- attrs.defaultCheckedBackground = ta.getResourceId(R.styleable.NCalendar_defaultCheckedBackground, R.drawable.n_bg_checked_default);
-
- attrs.todayCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_white));
- attrs.todayUnCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_todaySolarUnCheckedTextColor));
- attrs.defaultCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_defaultSolarTextColor));
- attrs.defaultUnCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_defaultSolarTextColor));
- attrs.solarTextSize = ta.getDimension(R.styleable.NCalendar_solarTextSize, context.getResources().getDimension(R.dimen.N_solarTextSize));
- attrs.solarTextBold = ta.getBoolean(R.styleable.NCalendar_solarTextBold, context.getResources().getBoolean(R.bool.N_textBold));
-
- attrs.showLunar = ta.getBoolean(R.styleable.NCalendar_showLunar, context.getResources().getBoolean(R.bool.N_showLunar));
- attrs.todayCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_white));
- attrs.todayUnCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_todayCheckedColor));
- attrs.defaultCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_defaultLunarTextColor));
- attrs.defaultUnCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_defaultLunarTextColor));
- attrs.lunarTextSize = ta.getDimension(R.styleable.NCalendar_lunarTextSize, context.getResources().getDimension(R.dimen.N_lunarTextSize));
- attrs.lunarTextBold = ta.getBoolean(R.styleable.NCalendar_lunarTextBold, context.getResources().getBoolean(R.bool.N_textBold));
- attrs.lunarDistance = ta.getDimension(R.styleable.NCalendar_lunarDistance, context.getResources().getDimension(R.dimen.N_lunarDistance));
-
- attrs.pointLocation = ta.getInt(R.styleable.NCalendar_pointLocation, Attrs.UP);
- attrs.pointDistance = ta.getDimension(R.styleable.NCalendar_pointDistance, context.getResources().getDimension(R.dimen.N_pointDistance));
- attrs.todayCheckedPoint = ta.getResourceId(R.styleable.NCalendar_todayCheckedPoint, R.drawable.n_point_checked_today);
- attrs.todayUnCheckedPoint = ta.getResourceId(R.styleable.NCalendar_todayUnCheckedPoint, R.drawable.n_point_unchecked_today);
- attrs.defaultCheckedPoint = ta.getResourceId(R.styleable.NCalendar_defaultCheckedPoint, R.drawable.n_point_checked_default);
- attrs.defaultUnCheckedPoint = ta.getResourceId(R.styleable.NCalendar_defaultUnCheckedPoint, R.drawable.n_point_unchecked_default);
-
- attrs.showHolidayWorkday = ta.getBoolean(R.styleable.NCalendar_showHoliday, context.getResources().getBoolean(R.bool.N_showHolidayWorkday));
-
- attrs.todayCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_todayCheckedHoliday);
- attrs.todayUnCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_todayUnCheckedHoliday);
- attrs.defaultCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_defaultCheckedHoliday);
- attrs.defaultUnCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_defaultUnCheckedHoliday);
- attrs.todayCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_todayCheckedWorkday);
- attrs.todayUnCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_todayUnCheckedWorkday);
- attrs.defaultCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_defaultCheckedWorkday);
- attrs.defaultUnCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_defaultUnCheckedWorkday);
-
- attrs.holidayWorkdayTextSize = ta.getDimension(R.styleable.NCalendar_holidayWorkdayTextSize, context.getResources().getDimension(R.dimen.N_holidayWorkdayTextSize));
- attrs.holidayWorkdayTextBold = ta.getBoolean(R.styleable.NCalendar_holidayWorkdayTextBold, context.getResources().getBoolean(R.bool.N_textBold));
- attrs.holidayWorkdayDistance = ta.getDimension(R.styleable.NCalendar_holidayWorkdayDistance, context.getResources().getDimension(R.dimen.N_holidayWorkdayDistance));
- attrs.holidayWorkdayLocation = ta.getInt(R.styleable.NCalendar_holidayWorkdayLocation, Attrs.TOP_RIGHT);
- attrs.holidayText = ta.getString(R.styleable.NCalendar_holidayText);
- attrs.workdayText = ta.getString(R.styleable.NCalendar_workdayText);
- attrs.todayCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_white));
- attrs.todayUnCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor));
- attrs.defaultCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor));
- attrs.defaultUnCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor));
- attrs.todayCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_white));
- attrs.todayUnCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor));
- attrs.defaultCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor));
- attrs.defaultUnCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor));
-
- attrs.showNumberBackground = ta.getBoolean(R.styleable.NCalendar_showNumberBackground, context.getResources().getBoolean(R.bool.N_showNumberBackground));
- attrs.numberBackgroundTextSize = ta.getDimension(R.styleable.NCalendar_numberBackgroundTextSize, context.getResources().getDimension(R.dimen.N_numberBackgroundTextSize));
- attrs.numberBackgroundTextColor = ta.getColor(R.styleable.NCalendar_numberBackgroundTextColor, ContextCompat.getColor(context, R.color.N_todaySolarUnCheckedTextColor));
- attrs.numberBackgroundAlphaColor = ta.getInt(R.styleable.NCalendar_numberBackgroundAlphaColor, context.getResources().getInteger(R.integer.N_numberBackgroundAlphaColor));
-
- attrs.firstDayOfWeek = ta.getInt(R.styleable.NCalendar_firstDayOfWeek, Attrs.SUNDAY);
- attrs.allMonthSixLine = ta.getBoolean(R.styleable.NCalendar_allMonthSixLine, context.getResources().getBoolean(R.bool.N_allMonthSixLine));
- attrs.lastNextMonthClickEnable = ta.getBoolean(R.styleable.NCalendar_lastNextMonthClickEnable, context.getResources().getBoolean(R.bool.N_lastNextMonthClickEnable));
- attrs.calendarBackground = ta.getDrawable(R.styleable.NCalendar_calendarBackground);
- attrs.lastNextMothAlphaColor = ta.getInt(R.styleable.NCalendar_lastNextMothAlphaColor, context.getResources().getInteger(R.integer.N_lastNextMothAlphaColor));
- attrs.disabledAlphaColor = ta.getInt(R.styleable.NCalendar_disabledAlphaColor, context.getResources().getInteger(R.integer.N_disabledAlphaColor));
- attrs.disabledString = ta.getString(R.styleable.NCalendar_disabledString);
-
- attrs.defaultCalendar = ta.getInt(R.styleable.NCalendar_defaultCalendar, CalendarState.MONTH.getValue());
- attrs.calendarHeight = (int) ta.getDimension(R.styleable.NCalendar_calendarHeight, context.getResources().getDimension(R.dimen.N_calendarHeight));
- attrs.animationDuration = ta.getInt(R.styleable.NCalendar_animationDuration, context.getResources().getInteger(R.integer.N_animationDuration));
-
- attrs.stretchCalendarEnable =ta.getBoolean(R.styleable.NCalendar_stretchCalendarEnable, context.getResources().getBoolean(R.bool.N_stretchCalendarEnable));
- attrs.stretchCalendarHeight = (int) ta.getDimension(R.styleable.NCalendar_stretchCalendarHeight, context.getResources().getDimension(R.dimen.N_stretchCalendarHeight));
- attrs.stretchTextSize = ta.getDimension(R.styleable.NCalendar_stretchTextSize, context.getResources().getDimension(R.dimen.N_stretchTextSize));
- attrs.stretchTextBold = ta.getBoolean(R.styleable.NCalendar_stretchTextBold, context.getResources().getBoolean(R.bool.N_textBold));
- attrs.stretchTextColor = ta.getColor(R.styleable.NCalendar_stretchTextColor, ContextCompat.getColor(context, R.color.N_stretchTextColor));
- attrs.stretchTextDistance = ta.getDimension(R.styleable.NCalendar_stretchTextDistance, context.getResources().getDimension(R.dimen.N_stretchTextDistance));
-
- ta.recycle();
- return attrs;
-
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/CalendarUtil.java b/ncalendar/src/main/java/com/necer/utils/CalendarUtil.java
deleted file mode 100644
index b3f2fc23..00000000
--- a/ncalendar/src/main/java/com/necer/utils/CalendarUtil.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package com.necer.utils;
-
-import android.content.Context;
-import android.util.TypedValue;
-
-import com.necer.entity.CalendarDate;
-import com.necer.entity.Lunar;
-
-import org.joda.time.LocalDate;
-import org.joda.time.Months;
-import org.joda.time.Weeks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by necer on 2017/6/9.
- */
-
-public class CalendarUtil {
-
-
- /**
- * 两个日期是否同月
- */
- public static boolean isEqualsMonth(LocalDate date1, LocalDate date2) {
- return date1.getYear() == date2.getYear() && date1.getMonthOfYear() == date2.getMonthOfYear();
- }
-
-
- /**
- * 第一个是不是第二个的上一个月,只在此处有效
- *
- * @param date1
- * @param date2
- * @return
- */
- public static boolean isLastMonth(LocalDate date1, LocalDate date2) {
- LocalDate date = date2.plusMonths(-1);
- return date1.getMonthOfYear() == date.getMonthOfYear();
- }
-
-
- /**
- * 第一个是不是第二个的下一个月,只在此处有效
- *
- * @param date1
- * @param date2
- * @return
- */
- public static boolean isNextMonth(LocalDate date1, LocalDate date2) {
- LocalDate date = date2.plusMonths(1);
- return date1.getMonthOfYear() == date.getMonthOfYear();
- }
-
-
- /**
- * 获得两个日期距离几个月
- *
- * @return
- */
- public static int getIntervalMonths(LocalDate date1, LocalDate date2) {
- date1 = date1.withDayOfMonth(1);
- date2 = date2.withDayOfMonth(1);
- return Months.monthsBetween(date1, date2).getMonths();
- }
-
- /**
- * 获得两个日期距离几周
- *
- * @param date1
- * @param date2
- * @param type 一周
- * @return
- */
- public static int getIntervalWeek(LocalDate date1, LocalDate date2, int type) {
-
- if (type == Attrs.MONDAY) {
- date1 = getMonFirstDayOfWeek(date1);
- date2 = getMonFirstDayOfWeek(date2);
- } else {
- date1 = getSunFirstDayOfWeek(date1);
- date2 = getSunFirstDayOfWeek(date2);
- }
-
- return Weeks.weeksBetween(date1, date2).getWeeks();
-
- }
-
-
- /**
- * 是否是今天
- *
- * @param date
- * @return
- */
- public static boolean isToday(LocalDate date) {
- return new LocalDate().equals(date);
- }
-
- /**
- * @param localDate
- * @param weekType 300,周日,301周一
- * @return
- */
- public static List getMonthCalendar(LocalDate localDate, int weekType, boolean isAllMonthSixLine) {
-
- LocalDate lastMonthDate = localDate.plusMonths(-1);//上个月
- LocalDate nextMonthDate = localDate.plusMonths(1);//下个月
-
- int days = localDate.dayOfMonth().getMaximumValue();//当月天数
- int lastMonthDays = lastMonthDate.dayOfMonth().getMaximumValue();//上个月的天数
- int firstDayOfWeek = new LocalDate(localDate.getYear(), localDate.getMonthOfYear(), 1).getDayOfWeek();//当月第一天周几
- int endDayOfWeek = new LocalDate(localDate.getYear(), localDate.getMonthOfYear(), days).getDayOfWeek();//当月最后一天周几
-
- List dateList = new ArrayList<>();
-
-
- //周一开始的
- if (weekType == Attrs.MONDAY) {
-
- //周一开始的
- for (int i = 0; i < firstDayOfWeek - 1; i++) {
- LocalDate date = new LocalDate(lastMonthDate.getYear(), lastMonthDate.getMonthOfYear(), lastMonthDays - (firstDayOfWeek - i - 2));
- dateList.add(date);
- }
- for (int i = 0; i < days; i++) {
- LocalDate date = new LocalDate(localDate.getYear(), localDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
- for (int i = 0; i < 7 - endDayOfWeek; i++) {
- LocalDate date = new LocalDate(nextMonthDate.getYear(), nextMonthDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
-
- } else {
- //上个月
- if (firstDayOfWeek != 7) {
- for (int i = 0; i < firstDayOfWeek; i++) {
- LocalDate date = new LocalDate(lastMonthDate.getYear(), lastMonthDate.getMonthOfYear(), lastMonthDays - (firstDayOfWeek - i - 1));
- dateList.add(date);
- }
- }
- //当月
- for (int i = 0; i < days; i++) {
- LocalDate date = new LocalDate(localDate.getYear(), localDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
- //下个月
- if (endDayOfWeek == 7) {
- endDayOfWeek = 0;
- }
- for (int i = 0; i < 6 - endDayOfWeek; i++) {
- LocalDate date = new LocalDate(nextMonthDate.getYear(), nextMonthDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
- }
-
- //某些年的2月份28天,又正好日历只占4行
- if (dateList.size() == 28) {
- for (int i = 0; i < 7; i++) {
- LocalDate date = new LocalDate(nextMonthDate.getYear(), nextMonthDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
- }
-
- //是否所有月份都6行
- if (isAllMonthSixLine && dateList.size() == 35) {
- LocalDate endLocalDate = dateList.get(dateList.size() - 1);
- int dayOfMonth = endLocalDate.getDayOfMonth();
- //如果是当月最后一天,直接加上下个月的7天,如果不是当月了,已经是下月了,就顺着下月数7天
- if (dayOfMonth == days) {
- for (int i = 0; i < 7; i++) {
- LocalDate date = new LocalDate(nextMonthDate.getYear(), nextMonthDate.getMonthOfYear(), i + 1);
- dateList.add(date);
- }
- } else {
- for (int i = 0; i < 7; i++) {
- LocalDate date = new LocalDate(nextMonthDate.getYear(), nextMonthDate.getMonthOfYear(), dayOfMonth + i + 1);
- dateList.add(date);
- }
- }
- }
-
-
- return dateList;
-
- }
-
-
- /**
- * 周视图的数据
- *
- * @param localDate
- * @return
- */
- public static List getWeekCalendar(LocalDate localDate, int type) {
- List dateList = new ArrayList<>();
-
- if (type == Attrs.MONDAY) {
- localDate = getMonFirstDayOfWeek(localDate);
- } else {
- localDate = getSunFirstDayOfWeek(localDate);
- }
-
- for (int i = 0; i < 7; i++) {
- LocalDate date = localDate.plusDays(i);
- dateList.add(date);
- }
- return dateList;
- }
-
-
- public static List getHolidayList() {
- return HolidayUtil.holidayList;
- }
-
- public static List getWorkdayList() {
- return HolidayUtil.workdayList;
- }
-
-
- /**
- * 转化一周从周日开始
- *
- * @param date
- * @return
- */
- public static LocalDate getSunFirstDayOfWeek(LocalDate date) {
- if (date.dayOfWeek().get() == 7) {
- return date;
- } else {
- return date.minusWeeks(1).withDayOfWeek(7);
- }
- }
-
- /**
- * 转化一周从周一开始
- *
- * @param date
- * @return
- */
- public static LocalDate getMonFirstDayOfWeek(LocalDate date) {
- return date.dayOfWeek().withMinimumValue();
- }
-
-
- /**
- * 获取CalendarDate CalendarDate包含需要显示的信息 农历,节气等
- *
- * @param localDate
- * @return
- */
- public static CalendarDate getCalendarDate(LocalDate localDate) {
- CalendarDate calendarDate = new CalendarDate();
- int solarYear = localDate.getYear();
- int solarMonth = localDate.getMonthOfYear();
- int solarDay = localDate.getDayOfMonth();
- Lunar lunar = LunarUtil.getLunar(solarYear, solarMonth, solarDay);
-
- LocalDate nextLocalDate = localDate.plusDays(1);
- Lunar nextLunar = LunarUtil.getLunar(nextLocalDate.getYear(), nextLocalDate.getMonthOfYear(), nextLocalDate.getDayOfMonth());
-
- calendarDate.lunar = lunar;
- calendarDate.localDate = localDate;
- calendarDate.solarTerm = SolarTermUtil.getSolatName(solarYear, (solarMonth < 10 ? ("0" + solarMonth) : (solarMonth + "")) + solarDay);
- calendarDate.solarHoliday = HolidayUtil.getSolarHoliday(solarYear, solarMonth, solarDay);
- calendarDate.lunarHoliday = HolidayUtil.getLunarHoliday(lunar, nextLunar);
-
- return calendarDate;
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/DrawableUtil.java b/ncalendar/src/main/java/com/necer/utils/DrawableUtil.java
deleted file mode 100644
index ab792270..00000000
--- a/ncalendar/src/main/java/com/necer/utils/DrawableUtil.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.necer.utils;
-
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-/**
- * Created by necer on 2020/3/27.
- */
-public class DrawableUtil {
-
-
- /**
- * 获取绘制Drawable的矩形
- * @param centerX
- * @param centerY
- * @param drawable
- * @return
- */
- public static Rect getDrawableBounds(int centerX, int centerY, Drawable drawable) {
- return new Rect(centerX - drawable.getIntrinsicWidth() / 2,
- centerY - drawable.getIntrinsicHeight() / 2,
- centerX + drawable.getIntrinsicWidth() / 2,
- centerY + drawable.getIntrinsicHeight() / 2);
- }
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/HolidayUtil.java b/ncalendar/src/main/java/com/necer/utils/HolidayUtil.java
deleted file mode 100644
index aef0f1c2..00000000
--- a/ncalendar/src/main/java/com/necer/utils/HolidayUtil.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.necer.utils;
-
-import com.necer.entity.Lunar;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Created by necer on 2018/11/16.
- */
-public class HolidayUtil {
-
-
- /**
- * 根据公历获取假期
- *
- * @return
- */
- public static String getSolarHoliday(int solarYear, int solarMonth, int solarDay) {
- String message = "";
- if (solarMonth == 1 && solarDay == 1) {
- message = "元旦";
- } else if (solarMonth == 2 && solarDay == 14) {
- message = "情人节";
- } else if (solarMonth == 3 && solarDay == 8) {
- message = "妇女节";
- } else if (solarMonth == 3 && solarDay == 12) {
- message = "植树节";
- } else if (solarMonth == 3 && solarDay == 15) {
- message = "消费者";
- } else if (solarMonth == 4) {
- if (solarDay == 1) {
- message = "愚人节";
- } else if (solarDay >= 4 && solarDay <= 6) {
- if (solarYear <= 1999) {
- int compare = (int) (((solarYear - 1900) * 0.2422 + 5.59) - ((solarYear - 1900) / 4));
- if (compare == solarDay) {
- message = "清明节";
- }
- } else {
- int compare = (int) (((solarYear - 2000) * 0.2422 + 4.81) - ((solarYear - 2000) / 4));
- if (compare == solarDay) {
- message = "清明节";
- }
- }
- }
- } else if (solarMonth == 5 && solarDay == 1) {
- message = "劳动节";
- } else if (solarMonth == 5 && solarDay == 4) {
- message = "青年节";
- } else if (solarMonth == 6 && solarDay == 1) {
- message = "儿童节";
- } else if (solarMonth == 7 && solarDay == 1) {
- message = "建党节";
- } else if (solarMonth == 8 && solarDay == 1) {
- message = "建军节";
- } else if (solarMonth == 9 && solarDay == 10) {
- message = "教师节";
- } else if (solarMonth == 10 && solarDay == 1) {
- message = "国庆节";
- }
- return message;
- }
-
-
- /**
- * 用于获取中国的传统节日
- *
- * @return 中国传统节日
- */
- public static String getLunarHoliday(Lunar lunar, Lunar nextLunar) {
- int lunarMonth = lunar.lunarMonth;
- int lunarDay = lunar.lunarDay;
- String message = "";
- if (lunarMonth == 1 && lunarDay == 1) {
- message = "春节";
- } else if (lunarMonth == 1 && lunarDay == 15) {
- message = "元宵节";
- } else if (lunarMonth == 2 && lunarDay == 2) {
- message = "龙抬头";
- } else if (lunarMonth == 5 && lunarDay == 5) {
- message = "端午节";
- } else if (lunarMonth == 7 && lunarDay == 7) {
- message = "七夕";
- } else if (lunarMonth == 7 && lunarDay == 15) {
- message = "中元节";
- } else if (lunarMonth == 8 && lunarDay == 15) {
- message = "中秋节";
- } else if (lunarMonth == 9 && lunarDay == 9) {
- message = "重阳节";
- } else if (lunarMonth == 12 && lunarDay == 8) {
- message = "腊八节";
- } else if (lunarMonth == 12 && lunarDay == 23) {
- message = "小年";
- } else if (lunarMonth == 12 && lunar.lunarMonth != nextLunar.lunarMonth) {
- message = "除夕";
- }
- return message;
- }
-
- //法定节假日 休息的日期
- public static List holidayList = Arrays.asList(
- "2017-12-30", "2017-12-31", "2018-01-01", "2018-02-15", "2018-02-16", "2018-02-17", "2018-02-18", "2018-02-19", "2018-02-20", "2018-02-21", "2018-04-05",
- "2018-04-06", "2018-04-07", "2018-04-29", "2018-04-30", "2018-05-01", "2018-06-16", "2018-06-17", "2018-06-18", "2018-09-22", "2018-09-23", "2018-09-24",
- "2018-10-01", "2018-10-02", "2018-10-03", "2018-10-04", "2018-10-05", "2018-10-06", "2018-10-07", "2018-12-30", "2018-12-31", "2019-01-01", "2019-02-04",
- "2019-02-05", "2019-02-06", "2019-02-07", "2019-02-08", "2019-02-09", "2019-02-10", "2019-04-05", "2019-04-06", "2019-04-07", "2019-05-01", "2019-05-02",
- "2019-05-03", "2019-05-04", "2019-06-07", "2019-06-08", "2019-06-09", "2019-09-13", "2019-09-14", "2019-09-15", "2019-10-01", "2019-10-02", "2019-10-03",
- "2019-10-04", "2019-10-05", "2019-10-06", "2019-10-07", "2020-01-01", "2020-01-24", "2020-01-25", "2020-01-26", "2020-01-27", "2020-01-28", "2020-01-29",
- "2020-01-30", "2020-01-31", "2020-02-01", "2020-02-02", "2020-04-04", "2020-04-05", "2020-04-06", "2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04",
- "2020-05-05", "2020-06-25", "2020-06-26", "2020-06-27", "2020-10-01", "2020-10-02", "2020-10-03", "2020-10-04", "2020-10-05", "2020-10-06", "2020-10-07",
- "2020-10-08", "2021-01-01", "2021-01-02", "2021-01-03", "2021-02-11", "2021-02-12", "2021-02-13", "2021-02-14", "2021-02-15", "2021-02-16", "2021-02-17",
- "2021-04-03", "2021-04-04", "2021-04-05", "2021-05-01", "2021-05-02", "2021-05-03", "2021-05-04", "2021-05-05", "2021-06-12", "2021-06-13", "2021-06-14",
- "2021-09-19", "2021-09-20", "2021-09-21", "2021-10-01", "2021-10-02", "2021-10-03", "2021-10-04", "2021-10-05", "2021-10-06", "2021-10-07");
-
- //补班的日期
- public static List workdayList = Arrays.asList(
- "2018-02-11", "2018-02-24", "2018-04-08", "2018-04-28", "2018-09-29", "2018-04-30", "2018-12-29", "2019-02-02", "2019-02-03", "2019-04-28", "2019-05-05",
- "2019-09-29", "2019-10-12", "2020-01-19", "2020-04-26", "2020-05-09", "2020-06-28", "2020-09-27", "2020-10-10", "2021-02-07", "2021-02-20", "2021-04-25",
- "2021-05-08", "2021-09-18", "2021-09-26", "2021-10-09");
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/LunarUtil.java b/ncalendar/src/main/java/com/necer/utils/LunarUtil.java
deleted file mode 100644
index 4f5f2b43..00000000
--- a/ncalendar/src/main/java/com/necer/utils/LunarUtil.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package com.necer.utils;
-
-
-import com.necer.entity.Lunar;
-
-/**
- * Created by Jimmy on 2017/1/9 0009.
- * 农历工具类
- */
-public class LunarUtil {
-
- /**
- * 支持转换的最小农历年份
- */
- private static final int MIN_YEAR = 1900;
-
- /**
- * 用于保存中文的月份
- */
- private final static String CHINESE_NUMBER[] = {"一", "二", "三", "四", "五",
- "六", "七", "八", "九", "十", "冬", "腊"};
-
-
- /**
- * 用来表示1900年到2099年间农历年份的相关信息,共24位bit的16进制表示,其中:
- * 1. 前4位表示该年闰哪个月;
- * 2. 5-17位表示农历年份13个月的大小月分布,0表示小,1表示大;
- * 3. 最后7位表示农历年首(正月初一)对应的公历日期。
- * 以2014年的数据0x955ABF为例说明:
- * 1001 0101 0101 1010 1011 1111
- * 闰九月 农历正月初一对应公历1月31号
- */
- private static final int LUNAR_INFO[] = {
- 0x84B6BF,/*1900*/
- 0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A,/*1901-1910*/
- 0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754,/*1911-1920*/
- 0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E,/*1921-1930*/
- 0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48,/*1931-1940*/
- 0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51,/*1941-1950*/
- 0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C,/*1951-1960*/
- 0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46,/*1961-1970*/
- 0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50,/*1971-1980*/
- 0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB,/*1981-1990*/
- 0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645,/*1991-2000*/
- 0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E,/*2001-2010*/
- 0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9,/*2011-2020*/
- 0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6a573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43,/*2021-2030*/
- 0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C,/*2031-2040*/
- 0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37,/*2041-2050*/
- 0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42,/*2051-2060*/
- 0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B,/*2061-2070*/
- 0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6,/*2071-2080*/
- 0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E,/*2081-2090*/
- 0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 /*2091-2099*/
- };
-
- private static int[] lunar_month_days = {1887, 0x1694, 0x16aa, 0x4ad5, 0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a,
- 0xd54, 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, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a, 0x136a5, 0xda4, 0x15ac};
-
- private static int[] solar_1_1 = {1887, 0xec04c, 0xec23f, 0xec435, 0xec649, 0xec83e, 0xeca51, 0xecc46, 0xece3a,
- 0xed04d, 0xed242, 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, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444, 0x107638, 0x10784c, 0x107a3f, 0x107c53,
- 0x107e48};
-
-
- private static String[] Gan = {"癸", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬"};
- private static String[] Zhi = {"亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌"};
- private static String[] Animals = {"猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗"};
- private static String chineseTen[] = {"初", "十", "廿", "卅"};
-
-
- private static int getBitInt(int data, int length, int shift) {
- return (data & (((1 << length) - 1) << shift)) >> shift;
- }
-
- private static long solarToInt(int y, int m, int d) {
- m = (m + 9) % 12;
- y = y - m / 10;
- return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
- }
-
- /**
- * 公历转农历
- */
- public static Lunar getLunar(int solarYear, int solarMonth, int solarDay) {
- Lunar lunar = new Lunar();
- int index = solarYear - solar_1_1[0];
- int data = (solarYear << 9) | (solarMonth << 5) | (solarDay);
- int solar11 = 0;
- if (solar_1_1[index] > data) {
- index--;
- }
- solar11 = solar_1_1[index];
- int y = getBitInt(solar11, 12, 9);
- int m = getBitInt(solar11, 4, 5);
- int d = getBitInt(solar11, 5, 0);
- long offset = solarToInt(solarYear, solarMonth, solarDay) - solarToInt(y, m, d);
-
- int days = lunar_month_days[index];
- int leap = getBitInt(days, 4, 13);
-
- int lunarY = index + solar_1_1[0];
- int lunarM = 1;
- int lunarD = 1;
- offset += 1;
- for (int i = 0; i < 13; i++) {
- int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
- if (offset > dm) {
- lunarM++;
- offset -= dm;
- } else {
- break;
- }
- }
- lunarD = (int) (offset);
- lunar.lunarYear = lunarY;
- lunar.lunarMonth = lunarM;
- lunar.isLeap = false;
- if (leap != 0 && lunarM > leap) {
- lunar.lunarMonth = lunarM - 1;
- if (lunarM == leap + 1) {
- lunar.isLeap = true;
- lunar.leapMonth = lunar.lunarMonth;
- }
- }
-
- lunar.lunarDay = lunarD;
- lunar.chineseEra = getGan(lunar.lunarYear) + getZhi(lunar.lunarYear);
- lunar.animals = getAnimalString(lunar.lunarYear);
- lunar.lunarYearStr = getGan(lunar.lunarYear) + getZhi(lunar.lunarYear) + getAnimalString(lunar.lunarYear);
- lunar.lunarMonthStr = getMonthStr(lunar.lunarMonth, lunar.isLeap);
- lunar.lunarDayStr = getDayStr(lunar.lunarDay);
- lunar.lunarOnDrawStr = getDrawStr(lunar.lunarMonth, lunar.lunarDay, lunar.lunarDayStr, lunar.isLeap);
-
- return lunar;
- }
-
-
- /**
- * 取农历年生肖
- *
- * @return 农历年生肖(例 : 2000年龙年)
- */
- private static String getAnimalString(int lunarYear) {
- return Animals[(lunarYear - 3) % 12];
- }
-
- private static String getGan(int lunarYear) {
- return Gan[(lunarYear - 3) % 10];
- }
-
- private static String getZhi(int lunarYear) {
- return Zhi[(lunarYear - 3) % 12];
- }
-
- private static String getMonthStr(int lunarMonth, boolean isLeap) {
- return isLeap ? "闰" : "" + CHINESE_NUMBER[lunarMonth - 1] + "月";
- }
-
- private static String getDrawStr(int lunatMonth, int lunatDay, String lunarDayStr, boolean isLeap) {
- String relust = "";
- if ("初一".equals(lunarDayStr) && isLeap) {
- relust = "闰" + CHINESE_NUMBER[lunatMonth - 1] + "月";
- } else if ("初一".equals(lunarDayStr)) {
- relust = CHINESE_NUMBER[lunatMonth - 1] + "月";
- } else if (lunatDay == 10) {
- relust = "初十";
- } else {
- int n = lunatDay % 10 == 0 ? 9 : (lunatDay % 10 - 1);
- relust = chineseTen[lunatDay / 10] + CHINESE_NUMBER[n];
- }
- return relust;
- }
-
- private static String getDayStr(int lunatDay) {
- if (lunatDay == 10) {
- return "初十";
- } else {
- int n = lunatDay % 10 == 0 ? 9 : (lunatDay % 10 - 1);
- return chineseTen[lunatDay / 10] + CHINESE_NUMBER[n];
- }
- }
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/NAttrs.kt b/ncalendar/src/main/java/com/necer/utils/NAttrs.kt
new file mode 100644
index 00000000..b5e45c01
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/NAttrs.kt
@@ -0,0 +1,470 @@
+package com.necer.utils
+
+import android.graphics.drawable.Drawable
+
+/**
+ * @author necer
+ * @date 2017/6/13
+ */
+object NAttrs {
+
+
+ /* 日历通用属性 */
+
+ /**
+ * 默认展示的日历 月->month 周->week 默认月
+ */
+ var defaultCalendar = 0
+
+
+ /**
+ * 日历一周开始是周日或周一 周日->monday 周一->monday 默认周日
+ */
+ var firstDayOfWeek = 0
+
+ /**
+ * 日历中 月日历的高度 默认300dp 周日历高度为 calendarHeight/5
+ */
+ var calendarHeight = 0
+
+ /**
+ * 日历顶部星期的高度 默认 wrap_content
+ */
+ var weekBarHeight = 0
+
+ /**
+ * 日历是否可拉伸 拉伸是月状态下继续下拉到达的状态
+ */
+ var stretchCalendarEnable = false
+
+ /**
+ * 拉伸后日历的高度 必须比calendarHeight高度高
+ */
+ var stretchCalendarHeight = 0
+
+ /**
+ * 日历 月周状态变化时松手后的动画时间 默认 200毫秒
+ */
+ var animationDuration = 0
+
+ /**
+ * 月日历是否全部6行
+ */
+ var allMonthSixLine = false
+
+ /**
+ * 日历背景 可设置Drawable背景,设置了这个数字背景失效
+ */
+ var calendarBackground: Drawable? = null
+
+ /**
+ * 是否显示数字背景 显示当前月
+ */
+ var showNumberBackground = false
+
+ /**
+ * 数字背景字体大小 默认 240sp
+ */
+ var numberBackgroundTextSize = 0f
+
+ /**
+ * 数字背景字体颜色
+ */
+ var numberBackgroundTextColor = 0
+
+ /**
+ * 背景透明度 取值0-225 默认50
+ */
+ var backgroundAlphaColor = 0
+
+ /**
+ * 月日历上下月是否可点击
+ */
+ var lastNextMonthClickEnable = false
+
+ /**
+ * 日历左右是否可滑动
+ */
+ var horizontalScrollEnable = false
+
+
+ /**
+ * 顶部周文字颜色
+ */
+ var weekBarTextColor=0
+
+ /**
+ * 顶部周文字大小
+ */
+ var weekBarTextSize=0f
+
+ /**
+ * 顶部周背景色
+ */
+ var weekBarBackgroundColor = 0
+
+
+
+ /* 日历UI属性 UI属性仅针对内置的InnerPainter,如果使用自定义CalendarPainter不生效,需自行实现需要的功能 */
+
+
+ /**
+ * 今天选中的背景 shape drawable
+ */
+ var todayCheckedBackground = 0
+
+ /**
+ * 其他日期选中的背景 shape drawable
+ */
+ var defaultCheckedBackground = 0
+
+ /**
+ * 公历日期属性
+ * 今天选中时的公历字体颜色 默认白色
+ */
+ var todayCheckedSolarTextColor = 0
+
+ /**
+ * 公历日期属性
+ * 今天不选中的公历字体颜色
+ */
+ var todayUnCheckedSolarTextColor = 0
+
+ /**
+ * 公历日期属性
+ * 默认选中的公历字体颜色
+ */
+ var defaultCheckedSolarTextColor = 0
+
+ /**
+ * 公历日期属性
+ * 默认不选中公历字体颜色
+ */
+ var defaultUnCheckedSolarTextColor = 0
+
+ /**
+ * 默认每页选中时,翻页选中第一个日期
+ */
+ var defaultCheckedFirstDate = false
+
+ /**
+ * 公历日期属性
+ * 公历字体大小 默认18sp
+ */
+ var solarTextSize = 0f
+
+ /**
+ * 公历日期属性
+ * 公历字体是否加粗
+ */
+ var solarTextBold = false
+
+ /**
+ * 标记日期属性
+ * 今天选中时标记
+ */
+ var todayCheckedPoint = 0
+
+ /**
+ * 标记日期属性
+ * 今天不选中时标记
+ */
+ var todayUnCheckedPoint = 0
+
+ /**
+ * 标记日期属性
+ * 默认选中时标记
+ */
+ var defaultCheckedPoint = 0
+
+ /**
+ * 标记日期属性
+ * 默认不选中时标记
+ */
+ var defaultUnCheckedPoint = 0
+
+ /**
+ * 标记日期属性
+ * up在上面 down在下面 默认上up
+ */
+ var pointLocation = 0
+
+ /**
+ * 标记日期属性
+ * 标记点到文字中心的距离 默认20dp
+ */
+ var pointDistance = 0f
+
+ /**
+ * 节假日日期属性 drawable
+ * 今天选中时节假日
+ */
+ var todayCheckedHoliday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 今天不选中时节假日
+ */
+ var todayUnCheckedHoliday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 默认选中时节假日
+ */
+ var defaultCheckedHoliday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 默认不选中时节假日
+ */
+ var defaultUnCheckedHoliday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 今天选中时工作日
+ */
+ var todayCheckedWorkday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 今天不选中工作日
+ */
+ var todayUnCheckedWorkday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 默认选中时工作日
+ */
+ var defaultCheckedWorkday: Drawable? = null
+
+ /**
+ * 节假日日期属性 drawable
+ * 默认不选中时工作日
+ */
+ var defaultUnCheckedWorkday: Drawable? = null
+
+ /**
+ * 节假日日期属性 text
+ * 是否显示节假日和工作日标记 默认true
+ */
+ var showHolidayWorkday = true
+
+ /**
+ * 节假日日期属性 text
+ * 节假日文字 默认 休
+ */
+ var holidayText: String? = null
+
+ /**
+ * 节假日日期属性 text
+ * 工作日文字 默认 班
+ */
+ var workdayText: String? = null
+
+ /**
+ * 节假日日期属性 text
+ * 字体大小 默认 10sp
+ */
+ var holidayWorkdayTextSize = 0f
+
+ /**
+ * 节假日日期属性 text
+ * 是否加粗
+ */
+ var holidayWorkdayTextBold = false
+
+ /**
+ * 节假日日期属性 text
+ * 文字距离中心距离 默认 15dp
+ */
+ var holidayWorkdayDistance = 0f
+
+ /**
+ * 节假日日期属性 text
+ * 文字的位置 分别为 top_right、top_left、bottom_right、bottom_left,默认为 top_right 右上角
+ */
+ var holidayWorkdayLocation = 0
+
+ /**
+ * 节假日日期属性 text
+ * 今天选中时节假日字体颜色 默认白色
+ */
+ var todayCheckedHolidayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 今天未选中时节假日字体颜色
+ */
+ var todayUnCheckedHolidayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 默认选中时节假日字体颜色
+ */
+ var defaultCheckedHolidayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 默认未选中时节假日字体颜色
+ */
+ var defaultUnCheckedHolidayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 今天选中时工作日字体颜色
+ */
+ var todayCheckedWorkdayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 今天选中时工作日颜色
+ */
+ var todayUnCheckedWorkdayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 默认选中时工作日字体颜色
+ */
+ var defaultCheckedWorkdayTextColor = 0
+
+ /**
+ * 节假日日期属性 text
+ * 默认选中时工作日字体颜色
+ */
+ var defaultUnCheckedWorkdayTextColor = 0
+
+ /**
+ * 农历属性
+ * 是否显示农历
+ */
+ var showLunar = false
+
+ /**
+ * 农历属性
+ * 今天选中时农历颜色
+ */
+ var todayCheckedLunarTextColor = 0
+
+ /**
+ * 农历属性
+ * 今天不选中时农历颜色
+ */
+ var todayUnCheckedLunarTextColor = 0
+
+ /**
+ * 农历属性
+ * 默认选中时农历颜色
+ */
+ var defaultCheckedLunarTextColor = 0
+
+ /**
+ * 农历属性
+ * 默认不选中时农历颜色
+ */
+ var defaultUnCheckedLunarTextColor = 0
+
+ /**
+ * 农历属性
+ * 农历字体大小 默认 10sp
+ */
+ var lunarTextSize = 0f
+
+ /**
+ * 农历属性
+ * 农历字体是否加粗
+ */
+ var lunarTextBold = false
+
+ /**
+ * 农历属性
+ * 农历文字到文字中心的距离 默认15dp
+ */
+ var lunarDistance = 0f
+
+ /**
+ * 上下月月的颜色透明度 默认 90 取值范围 0-225
+ */
+ var lastNextMothAlphaColor = 0
+
+
+ /**
+ * 不可用的日期颜色透明度 默认 50 取值范围 0-225
+ */
+ var disabledAlphaColor = 0
+
+ /**
+ * 点击不可用的日期提示语
+ */
+ var disabledString: String? = null
+
+ /**
+ * 拉伸显示的字体大小
+ */
+ var stretchTextSize = 0f
+
+ /**
+ * 拉伸字体加粗
+ */
+ var stretchTextBold = false
+
+ /**
+ * 拉伸显示的字体颜色
+ */
+ var stretchTextColor = 0
+
+ /**
+ * 拉伸显示的字体距离矩形中心的距离
+ */
+ var stretchTextDistance = 0f
+
+
+
+
+ /**
+ * 指示圆点的位置
+ * 在公历日期上面
+ */
+ const val UP = 200
+
+ /**
+ * 指示圆点的位置
+ * 在公历日期下面
+ */
+ const val DOWN = 201
+
+ /**
+ * 周的第一天
+ * 周日
+ */
+ const val SUNDAY = 300
+
+ /**
+ * 周的第一天
+ * 周一
+ */
+ const val MONDAY = 301
+
+ /**
+ * 节假日的位置
+ * 右上方
+ */
+ const val TOP_RIGHT = 400
+
+ /**
+ * 节假日的位置
+ * 左上方
+ */
+ const val TOP_LEFT = 401
+
+ /**
+ * 节假日的位置
+ * 右下方
+ */
+ const val BOTTOM_RIGHT = 402
+
+ /**
+ * 节假日的位置
+ * 左下方
+ */
+ const val BOTTOM_LEFT = 403
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/NAttrsUtil.kt b/ncalendar/src/main/java/com/necer/utils/NAttrsUtil.kt
new file mode 100644
index 00000000..f23f2681
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/NAttrsUtil.kt
@@ -0,0 +1,89 @@
+package com.necer.utils
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.core.content.ContextCompat
+import com.necer.enumeration.CalendarState
+import com.necer.R
+
+/**
+ * @author necer
+ * @date 2018/11/28
+ */
+object NAttrsUtil {
+ fun setAttrs(context: Context, attributeSet: AttributeSet?) {
+ val ta = context.obtainStyledAttributes(attributeSet, R.styleable.NCalendar)
+ NAttrs.todayCheckedBackground = ta.getResourceId(R.styleable.NCalendar_todayCheckedBackground, R.drawable.n_bg_checked_today)
+ NAttrs.defaultCheckedBackground = ta.getResourceId(R.styleable.NCalendar_defaultCheckedBackground, R.drawable.n_bg_checked_default)
+ NAttrs.todayCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_white))
+ NAttrs.todayUnCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_todaySolarUnCheckedTextColor))
+ NAttrs.defaultCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_defaultSolarTextColor))
+ NAttrs.defaultUnCheckedSolarTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedSolarTextColor, ContextCompat.getColor(context, R.color.N_defaultSolarTextColor))
+ NAttrs.solarTextSize = ta.getDimension(R.styleable.NCalendar_solarTextSize, context.resources.getDimension(R.dimen.N_solarTextSize))
+ NAttrs.weekBarTextSize = ta.getDimension(R.styleable.NCalendar_weekBarTextSize, context.resources.getDimension(R.dimen.N_weekBarTextSize))
+ NAttrs.solarTextBold = ta.getBoolean(R.styleable.NCalendar_solarTextBold, context.resources.getBoolean(R.bool.N_textBold))
+ NAttrs.showLunar = ta.getBoolean(R.styleable.NCalendar_showLunar, context.resources.getBoolean(R.bool.N_showLunar))
+ NAttrs.todayCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_white))
+ NAttrs.todayUnCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_todayCheckedColor))
+ NAttrs.defaultCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_defaultLunarTextColor))
+ NAttrs.defaultUnCheckedLunarTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedLunarTextColor, ContextCompat.getColor(context, R.color.N_defaultLunarTextColor))
+ NAttrs.lunarTextSize = ta.getDimension(R.styleable.NCalendar_lunarTextSize, context.resources.getDimension(R.dimen.N_lunarTextSize))
+ NAttrs.lunarTextBold = ta.getBoolean(R.styleable.NCalendar_lunarTextBold, context.resources.getBoolean(R.bool.N_textBold))
+ NAttrs.lunarDistance = ta.getDimension(R.styleable.NCalendar_lunarDistance, context.resources.getDimension(R.dimen.N_lunarDistance))
+ NAttrs.pointLocation = ta.getInt(R.styleable.NCalendar_pointLocation, NAttrs.UP)
+ NAttrs.pointDistance = ta.getDimension(R.styleable.NCalendar_pointDistance, context.resources.getDimension(R.dimen.N_pointDistance))
+ NAttrs.todayCheckedPoint = ta.getResourceId(R.styleable.NCalendar_todayCheckedPoint, R.drawable.n_point_checked_today)
+ NAttrs.todayUnCheckedPoint = ta.getResourceId(R.styleable.NCalendar_todayUnCheckedPoint, R.drawable.n_point_unchecked_today)
+ NAttrs.defaultCheckedPoint = ta.getResourceId(R.styleable.NCalendar_defaultCheckedPoint, R.drawable.n_point_checked_default)
+ NAttrs.defaultUnCheckedPoint = ta.getResourceId(R.styleable.NCalendar_defaultUnCheckedPoint, R.drawable.n_point_unchecked_default)
+ NAttrs.showHolidayWorkday = ta.getBoolean(R.styleable.NCalendar_showHolidayWorkday, context.resources.getBoolean(R.bool.N_showHolidayWorkday))
+ NAttrs.defaultCheckedFirstDate = ta.getBoolean(R.styleable.NCalendar_defaultCheckedFirstDate, context.resources.getBoolean(R.bool.N_defaultCheckedFirstDate))
+ NAttrs.todayCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_todayCheckedHoliday)
+ NAttrs.todayUnCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_todayUnCheckedHoliday)
+ NAttrs.defaultCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_defaultCheckedHoliday)
+ NAttrs.defaultUnCheckedHoliday = ta.getDrawable(R.styleable.NCalendar_defaultUnCheckedHoliday)
+ NAttrs.todayCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_todayCheckedWorkday)
+ NAttrs.todayUnCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_todayUnCheckedWorkday)
+ NAttrs.defaultCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_defaultCheckedWorkday)
+ NAttrs.defaultUnCheckedWorkday = ta.getDrawable(R.styleable.NCalendar_defaultUnCheckedWorkday)
+ NAttrs.holidayWorkdayTextSize = ta.getDimension(R.styleable.NCalendar_holidayWorkdayTextSize, context.resources.getDimension(R.dimen.N_holidayWorkdayTextSize))
+ NAttrs.holidayWorkdayTextBold = ta.getBoolean(R.styleable.NCalendar_holidayWorkdayTextBold, context.resources.getBoolean(R.bool.N_textBold))
+ NAttrs.holidayWorkdayDistance = ta.getDimension(R.styleable.NCalendar_holidayWorkdayDistance, context.resources.getDimension(R.dimen.N_holidayWorkdayDistance))
+ NAttrs.holidayWorkdayLocation = ta.getInt(R.styleable.NCalendar_holidayWorkdayLocation, NAttrs.TOP_RIGHT)
+ NAttrs.holidayText = ta.getString(R.styleable.NCalendar_holidayText)
+ NAttrs.workdayText = ta.getString(R.styleable.NCalendar_workdayText)
+ NAttrs.todayCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_white))
+ NAttrs.todayUnCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor))
+ NAttrs.defaultCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor))
+ NAttrs.defaultUnCheckedHolidayTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedHolidayTextColor, ContextCompat.getColor(context, R.color.N_holidayTextColor))
+ NAttrs.todayCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_todayCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_white))
+ NAttrs.todayUnCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_todayUnCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor))
+ NAttrs.defaultCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_defaultCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor))
+ NAttrs.defaultUnCheckedWorkdayTextColor = ta.getColor(R.styleable.NCalendar_defaultUnCheckedWorkdayTextColor, ContextCompat.getColor(context, R.color.N_workdayTextColor))
+ NAttrs.showNumberBackground = ta.getBoolean(R.styleable.NCalendar_showNumberBackground, context.resources.getBoolean(R.bool.N_showNumberBackground))
+ NAttrs.numberBackgroundTextSize = ta.getDimension(R.styleable.NCalendar_numberBackgroundTextSize, context.resources.getDimension(R.dimen.N_numberBackgroundTextSize))
+ NAttrs.numberBackgroundTextColor = ta.getColor(R.styleable.NCalendar_numberBackgroundTextColor, ContextCompat.getColor(context, R.color.N_todaySolarUnCheckedTextColor))
+ NAttrs.weekBarTextColor = ta.getColor(R.styleable.NCalendar_weekBarTextColor, ContextCompat.getColor(context, R.color.N_weekBarTextColor))
+ NAttrs.weekBarBackgroundColor = ta.getColor(R.styleable.NCalendar_weekBarBackgroundColor, ContextCompat.getColor(context, R.color.N_weekBarBackgroundColor))
+ NAttrs.backgroundAlphaColor = ta.getInt(R.styleable.NCalendar_backgroundAlphaColor, context.resources.getInteger(R.integer.N_backgroundAlphaColor))
+ NAttrs.firstDayOfWeek = ta.getInt(R.styleable.NCalendar_firstDayOfWeek, NAttrs.SUNDAY)
+ NAttrs.allMonthSixLine = ta.getBoolean(R.styleable.NCalendar_allMonthSixLine, context.resources.getBoolean(R.bool.N_allMonthSixLine))
+ NAttrs.lastNextMonthClickEnable = ta.getBoolean(R.styleable.NCalendar_lastNextMonthClickEnable, context.resources.getBoolean(R.bool.N_lastNextMonthClickEnable))
+ NAttrs.horizontalScrollEnable = ta.getBoolean(R.styleable.NCalendar_horizontalScrollEnable, context.resources.getBoolean(R.bool.N_horizontalScrollEnable))
+ NAttrs.calendarBackground = ta.getDrawable(R.styleable.NCalendar_calendarBackground)
+ NAttrs.lastNextMothAlphaColor = ta.getInt(R.styleable.NCalendar_lastNextMothAlphaColor, context.resources.getInteger(R.integer.N_lastNextMothAlphaColor))
+ NAttrs.disabledAlphaColor = ta.getInt(R.styleable.NCalendar_disabledAlphaColor, context.resources.getInteger(R.integer.N_disabledAlphaColor))
+ NAttrs.disabledString = ta.getString(R.styleable.NCalendar_disabledString)
+ NAttrs.defaultCalendar = ta.getInt(R.styleable.NCalendar_defaultCalendar, CalendarState.MONTH.getValue())
+ NAttrs.calendarHeight = ta.getDimension(R.styleable.NCalendar_calendarHeight, context.resources.getDimension(R.dimen.N_calendarHeight)).toInt()
+ NAttrs.weekBarHeight = ta.getDimension(R.styleable.NCalendar_weekBarHeight, context.resources.getDimension(R.dimen.N_weekBarHeight)).toInt()
+ NAttrs.animationDuration = ta.getInt(R.styleable.NCalendar_animationDuration, context.resources.getInteger(R.integer.N_animationDuration))
+ NAttrs.stretchCalendarEnable = ta.getBoolean(R.styleable.NCalendar_stretchCalendarEnable, context.resources.getBoolean(R.bool.N_stretchCalendarEnable))
+ NAttrs.stretchCalendarHeight = ta.getDimension(R.styleable.NCalendar_stretchCalendarHeight, context.resources.getDimension(R.dimen.N_stretchCalendarHeight)).toInt()
+ NAttrs.stretchTextSize = ta.getDimension(R.styleable.NCalendar_stretchTextSize, context.resources.getDimension(R.dimen.N_stretchTextSize))
+ NAttrs.stretchTextBold = ta.getBoolean(R.styleable.NCalendar_stretchTextBold, context.resources.getBoolean(R.bool.N_textBold))
+ NAttrs.stretchTextColor = ta.getColor(R.styleable.NCalendar_stretchTextColor, ContextCompat.getColor(context, R.color.N_stretchTextColor))
+ NAttrs.stretchTextDistance = ta.getDimension(R.styleable.NCalendar_stretchTextDistance, context.resources.getDimension(R.dimen.N_stretchTextDistance))
+ ta.recycle()
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/NDateUtil.kt b/ncalendar/src/main/java/com/necer/utils/NDateUtil.kt
new file mode 100644
index 00000000..e332dfca
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/NDateUtil.kt
@@ -0,0 +1,148 @@
+package com.necer.utils
+
+import java.time.DayOfWeek
+import java.time.LocalDate
+import java.time.temporal.ChronoUnit
+import java.time.temporal.TemporalAdjusters
+
+
+object NDateUtil {
+
+
+ fun getMonthDate(localDate: LocalDate, weekType: Int, isAllMonthSixLine: Boolean): List {
+ // weekType: 301 表示周一开始,其他表示周日开始
+ val firstDayOfWeek = if (weekType == NAttrs.MONDAY) DayOfWeek.MONDAY else DayOfWeek.SUNDAY
+
+ // 获取给定日期所在月份的第一天和最后一天
+ val firstDayOfMonth = localDate.with(TemporalAdjusters.firstDayOfMonth())
+ val lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth())
+
+ // 计算第一行开始的日期(基于weekType)
+ val startDate = firstDayOfMonth.minusDays((firstDayOfMonth.dayOfWeek.value - firstDayOfWeek.value + (if (firstDayOfWeek.value > firstDayOfMonth.dayOfWeek.value) 7 else 0)).toLong())
+
+ // 创建一个列表来保存日期
+ val dates = ArrayList()
+
+ // 填充日期,直到达到所需的行数
+ var currentDay = startDate
+ while (dates.size < 35 ) {
+ dates.add(currentDay)
+ currentDay = currentDay.plusDays(1)
+ }
+
+ if (isAllMonthSixLine || dates[dates.size - 1].isBefore(lastDayOfMonth)) {
+ while (dates.size < 42) {
+ dates.add(currentDay)
+ currentDay = currentDay.plusDays(1)
+ }
+ }
+ return dates
+ }
+
+
+ fun getWeekDate(localDate: LocalDate, weekType: Int): List {
+
+ val firstDayOfWeek = if (weekType == NAttrs.MONDAY) DayOfWeek.MONDAY else DayOfWeek.SUNDAY
+
+ // 获取该周的第一天
+ val firstDayOfWeekDate =
+ localDate.with(TemporalAdjusters.previousOrSame(firstDayOfWeek))
+
+ // 创建一个列表来保存日期
+ val weekDates = ArrayList()
+
+ // 填充一周的日期
+ for (dayOfWeek in 0..6) {
+ weekDates.add(firstDayOfWeekDate.plusDays(dayOfWeek.toLong()))
+ }
+
+ // 返回一周的日期列表
+ return weekDates
+ }
+
+
+ /**
+ * 获得两个日期距离几个月
+ *
+ * @return
+ */
+ fun getIntervalMonths(startDate: LocalDate, endDate: LocalDate): Int {
+ // 确保startDate在endDate之前
+ if (startDate.isAfter(endDate)) {
+ return -getIntervalMonths(endDate, startDate)
+ }
+ val date1 = LocalDate.of(startDate.year,startDate.month,1)
+ val date2 = LocalDate.of(endDate.year,endDate.month,1)
+
+ // 使用ChronoUnit.MONTHS来计算月份差异
+ val months = ChronoUnit.MONTHS.between(date1, date2)
+ return months.toInt() // 转换为int,因为月份差异应该是整数
+
+ }
+
+
+ /**
+ * 获得两个日期距离几周
+ *
+ * @param date1
+ * @param date2
+ * @param type 一周
+ * @return
+ */
+ fun getIntervalWeek(date1: LocalDate, date2: LocalDate, weekType: Int): Int {
+ // weekType: 301 表示周一开始, 其他表示周日开始
+ val firstDayOfWeek = if (weekType == NAttrs.MONDAY) DayOfWeek.MONDAY else DayOfWeek.SUNDAY
+
+ // 将两个日期都调整到它们所在周的第一天
+ val adjustedDate1 = date1.with(TemporalAdjusters.previousOrSame(firstDayOfWeek))
+ val adjustedDate2 = date2.with(TemporalAdjusters.previousOrSame(firstDayOfWeek))
+
+ // 计算天数差
+ val daysBetween = ChronoUnit.DAYS.between(adjustedDate1, adjustedDate2)
+
+ // 除以7得到周数(由于我们已将日期调整到周的第一天,因此直接除以7即可)
+ return (daysBetween / 7).toInt()
+ }
+
+
+ /**
+ * 两个日期是否同月
+ */
+ fun isEqualsMonth(date1: LocalDate, date2: LocalDate): Boolean {
+ return date1.year == date2.year && date1.monthValue == date2.monthValue
+ }
+
+
+ fun isToday(date: LocalDate?): Boolean {
+ // 获取今天的日期并与给定的日期进行比较
+ return LocalDate.now().isEqual(date)
+ }
+
+ /**
+ * 第一个是不是第二个的上一个月
+ *
+ * @param date1
+ * @param date2
+ * @return
+ */
+ fun isLastMonth(date1: LocalDate, date2: LocalDate): Boolean {
+ val date = date2.plusMonths(-1)
+ return date1.monthValue == date.monthValue
+ }
+
+
+ /**
+ * 第一个是不是第二个的下一个月
+ *
+ * @param date1
+ * @param date2
+ * @return
+ */
+ fun isNextMonth(date1: LocalDate, date2: LocalDate): Boolean {
+ val date = date2.plusMonths(1)
+ return date1.monthValue == date.monthValue
+ }
+
+
+}
+
diff --git a/ncalendar/src/main/java/com/necer/utils/SolarTermUtil.java b/ncalendar/src/main/java/com/necer/utils/SolarTermUtil.java
deleted file mode 100644
index 37cdfc92..00000000
--- a/ncalendar/src/main/java/com/necer/utils/SolarTermUtil.java
+++ /dev/null
@@ -1,285 +0,0 @@
-package com.necer.utils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 作者:Sun_LeiLei
- * 来源:CSDN
- * 原文:https://blog.csdn.net/sun_leilei/article/details/50148297
- * 版权声明:本文为博主原创文章,转载请附上博文链接!
- * Created by necer on 2018/11/16.
- */
-public class SolarTermUtil {
-
-
- private static final double D = 0.2422;
- private final static Map INCREASE_OFFSETMAP = new HashMap();// +1偏移
- private final static Map DECREASE_OFFSETMAP = new HashMap();// -1偏移
-
- /**
- * 24节气
- **/
- private static enum SolarTermsEnum {
- LICHUN, // --立春
- YUSHUI, // --雨水
- JINGZHE, // --惊蛰
- CHUNFEN, // 春分
- QINGMING, // 清明
- GUYU, // 谷雨
- LIXIA, // 立夏
- XIAOMAN, // 小满
- MANGZHONG, // 芒种
- XIAZHI, // 夏至
- XIAOSHU, // 小暑
- DASHU, // 大暑
- LIQIU, // 立秋
- CHUSHU, // 处暑
- BAILU, // 白露
- QIUFEN, // 秋分
- HANLU, // 寒露
- SHUANGJIANG, // 霜降
- LIDONG, // 立冬
- XIAOXUE, // 小雪
- DAXUE, // 大雪
- DONGZHI, // 冬至
- XIAOHAN, // 小寒
- DAHAN;// 大寒
- }
-
- static {
- DECREASE_OFFSETMAP.put(SolarTermsEnum.YUSHUI.name(),
- new Integer[]{2026});// 雨水
- INCREASE_OFFSETMAP.put(SolarTermsEnum.CHUNFEN.name(),
- new Integer[]{2084});// 春分
- INCREASE_OFFSETMAP.put(SolarTermsEnum.XIAOMAN.name(),
- new Integer[]{2008});// 小满
- INCREASE_OFFSETMAP.put(SolarTermsEnum.MANGZHONG.name(),
- new Integer[]{1902});// 芒种
- INCREASE_OFFSETMAP.put(SolarTermsEnum.XIAZHI.name(),
- new Integer[]{1928});// 夏至
- INCREASE_OFFSETMAP.put(SolarTermsEnum.XIAOSHU.name(), new Integer[]{
- 1925, 2016});// 小暑
- INCREASE_OFFSETMAP.put(SolarTermsEnum.DASHU.name(),
- new Integer[]{1922});// 大暑
- INCREASE_OFFSETMAP.put(SolarTermsEnum.LIQIU.name(),
- new Integer[]{2002});// 立秋
- INCREASE_OFFSETMAP.put(SolarTermsEnum.BAILU.name(),
- new Integer[]{1927});// 白露
- INCREASE_OFFSETMAP.put(SolarTermsEnum.QIUFEN.name(),
- new Integer[]{1942});// 秋分
- INCREASE_OFFSETMAP.put(SolarTermsEnum.SHUANGJIANG.name(),
- new Integer[]{2089});// 霜降
- INCREASE_OFFSETMAP.put(SolarTermsEnum.LIDONG.name(),
- new Integer[]{2089});// 立冬
- INCREASE_OFFSETMAP.put(SolarTermsEnum.XIAOXUE.name(),
- new Integer[]{1978});// 小雪
- INCREASE_OFFSETMAP.put(SolarTermsEnum.DAXUE.name(),
- new Integer[]{1954});// 大雪
- DECREASE_OFFSETMAP.put(SolarTermsEnum.DONGZHI.name(), new Integer[]{
- 1918, 2021});// 冬至
-
- INCREASE_OFFSETMAP.put(SolarTermsEnum.XIAOHAN.name(),
- new Integer[]{1982});// 小寒
- DECREASE_OFFSETMAP.put(SolarTermsEnum.XIAOHAN.name(),
- new Integer[]{2019});// 小寒
-
- INCREASE_OFFSETMAP.put(SolarTermsEnum.DAHAN.name(),
- new Integer[]{2082});// 大寒
- }
-
- // 定义一个二维数组,第一维数组存储的是20世纪的节气C值,第二维数组存储的是21世纪的节气C值,0到23个,依次代表立春、雨水...大寒节气的C值
- private static final double[][] CENTURY_ARRAY = {
- {4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86,
- 6.5, 22.2, 7.928, 23.65, 8.35, 23.95, 8.44, 23.822, 9.098,
- 24.218, 8.218, 23.08, 7.9, 22.6, 6.11, 20.84},
- {3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37,
- 7.108, 22.83, 7.5, 23.13, 7.646, 23.042, 8.318, 23.438,
- 7.438, 22.36, 7.18, 21.94, 5.4055, 20.12}};
-
- /**
- * @param year 年份
- * @param name 节气的名称
- * @return 返回节气是相应月份的第几天
- */
- public static int getSolarTermNum(int year, String name) {
-
- double centuryValue = 0;// 节气的世纪值,每个节气的每个世纪值都不同
- name = name.trim().toUpperCase();
- int ordinal = SolarTermsEnum.valueOf(name).ordinal();
-
- int centuryIndex = -1;
- if (year >= 1901 && year <= 2000) {// 20世纪
- centuryIndex = 0;
- } else if (year >= 2001 && year <= 2100) {// 21世纪
- centuryIndex = 1;
- } else {
- throw new RuntimeException("不支持此年份:" + year
- + ",目前只支持1901年到2100年的时间范围");
- }
- centuryValue = CENTURY_ARRAY[centuryIndex][ordinal];
- int dateNum = 0;
- /**
- * 计算 num =[Y*D+C]-L这是传说中的寿星通用公式
- * 公式解读:年数的后2位乘0.2422加C(即:centuryValue)取整数后,减闰年数
- */
- int y = year % 100;// 步骤1:取年分的后两位数
- if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {// 闰年
- if (ordinal == SolarTermsEnum.XIAOHAN.ordinal()
- || ordinal == SolarTermsEnum.DAHAN.ordinal()
- || ordinal == SolarTermsEnum.LICHUN.ordinal()
- || ordinal == SolarTermsEnum.YUSHUI.ordinal()) {
- // 注意:凡闰年3月1日前闰年数要减一,即:L=[(Y-1)/4],因为小寒、大寒、立春、雨水这两个节气都小于3月1日,所以
- // y = y-1
- y = y - 1;// 步骤2
- }
- }
- dateNum = (int) (y * D + centuryValue) - (int) (y / 4);// 步骤3,使用公式[Y*D+C]-L计算
- dateNum += specialYearOffset(year, name);// 步骤4,加上特殊的年分的节气偏移量
- return dateNum;
- }
-
- /**
- * 特例,特殊的年分的节气偏移量,由于公式并不完善,所以算出的个别节气的第几天数并不准确,在此返回其偏移量
- *
- * @param year 年份
- * @param name 节气名称
- * @return 返回其偏移量
- */
- private static int specialYearOffset(int year, String name) {
- int offset = 0;
- offset += getOffset(DECREASE_OFFSETMAP, year, name, -1);
- offset += getOffset(INCREASE_OFFSETMAP, year, name, 1);
-
- return offset;
- }
-
- private static int getOffset(Map map, int year,
- String name, int offset) {
- int off = 0;
- Integer[] years = map.get(name);
- if (null != years) {
- for (int i : years) {
- if (i == year) {
- off = offset;
- break;
- }
- }
- }
- return off;
- }
-
- private static int mYear;
- private static List mSolarData = new ArrayList();
- private static List mSolarName = new ArrayList();
-
- /**
- * 判断一天是什么节气 公历日期
- *
- * @param year
- * @param data 月份占两位,日不确定,如一月一日为:011,五月十日为0510
- * @return
- * @data2015-12-2下午2:49:32
- */
- public static String getSolatName(int year, String data) {
- if (year != mYear) {
- solarTermToString(year);
- }
- if (mSolarData.contains(data)) {
- return mSolarName.get(mSolarData.indexOf(data));
- } else {
- return null;
- }
- }
-
- private static void solarTermToString(int year) {
- mYear = year;
- if (mSolarData != null) {
- mSolarData.clear();
- } else {
- mSolarData = new ArrayList();
- }
- if (mSolarName != null) {
- mSolarName.clear();
- } else {
- mSolarName = new ArrayList();
- }
- // 1
- mSolarName.add("立春");
- mSolarData.add("02" + getSolarTermNum(year, SolarTermsEnum.LICHUN.name()));
- // 2
- mSolarName.add("雨水");
- mSolarData.add("02" + getSolarTermNum(year, SolarTermsEnum.YUSHUI.name()));
- // 3
- mSolarName.add("惊蛰");
- mSolarData.add("03" + getSolarTermNum(year, SolarTermsEnum.JINGZHE.name()));
- // 4
- mSolarName.add("春分");
- mSolarData.add("03" + getSolarTermNum(year, SolarTermsEnum.CHUNFEN.name()));
- // 5
- mSolarName.add("清明");
- mSolarData.add("04" + getSolarTermNum(year, SolarTermsEnum.QINGMING.name()));
- // 6
- mSolarName.add("谷雨");
- mSolarData.add("04" + getSolarTermNum(year, SolarTermsEnum.GUYU.name()));
- // 7
- mSolarName.add("立夏");
- mSolarData.add("05" + getSolarTermNum(year, SolarTermsEnum.LIXIA.name()));
- // 8
- mSolarName.add("小满");
- mSolarData.add("05" + getSolarTermNum(year, SolarTermsEnum.XIAOMAN.name()));
- // 9
- mSolarName.add("芒种");
- mSolarData.add("06" + getSolarTermNum(year, SolarTermsEnum.MANGZHONG.name()));
- // 10
- mSolarName.add("夏至");
- mSolarData.add("06" + getSolarTermNum(year, SolarTermsEnum.XIAZHI.name()));
- // 11
- mSolarName.add("小暑");
- mSolarData.add("07" + getSolarTermNum(year, SolarTermsEnum.XIAOSHU.name()));
- // 12
- mSolarName.add("大暑");
- mSolarData.add("07" + getSolarTermNum(year, SolarTermsEnum.DASHU.name()));
- // 13
- mSolarName.add("立秋");
- mSolarData.add("08" + getSolarTermNum(year, SolarTermsEnum.LIQIU.name()));
- // 14
- mSolarName.add("处暑");
- mSolarData.add("08" + getSolarTermNum(year, SolarTermsEnum.CHUSHU.name()));
- // 15
- mSolarName.add("白露");
- mSolarData.add("09" + getSolarTermNum(year, SolarTermsEnum.BAILU.name()));
- // 16
- mSolarName.add("秋分");
- mSolarData.add("09" + getSolarTermNum(year, SolarTermsEnum.QIUFEN.name()));
- // 17
- mSolarName.add("寒露");
- mSolarData.add("10" + getSolarTermNum(year, SolarTermsEnum.HANLU.name()));
- // 18
- mSolarName.add("霜降");
- mSolarData.add("10" + getSolarTermNum(year, SolarTermsEnum.SHUANGJIANG.name()));
- // 19
- mSolarName.add("立冬");
- mSolarData.add("11" + getSolarTermNum(year, SolarTermsEnum.LIDONG.name()));
- // 20
- mSolarName.add("小雪");
- mSolarData.add("11" + getSolarTermNum(year, SolarTermsEnum.XIAOXUE.name()));
- // 21
- mSolarName.add("大雪");
- mSolarData.add("12" + getSolarTermNum(year, SolarTermsEnum.DAXUE.name()));
- // 22
- mSolarName.add("冬至");
- mSolarData.add("12" + getSolarTermNum(year, SolarTermsEnum.DONGZHI.name()));
- // 23
- mSolarName.add("小寒");
- mSolarData.add("01" + getSolarTermNum(year, SolarTermsEnum.XIAOHAN.name()));
- // 24
- mSolarName.add("大寒");
- mSolarData.add("01" + getSolarTermNum(year, SolarTermsEnum.DAHAN.name()));
-
- }
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/ViewUtil.java b/ncalendar/src/main/java/com/necer/utils/ViewUtil.java
deleted file mode 100644
index bc1fb6f7..00000000
--- a/ncalendar/src/main/java/com/necer/utils/ViewUtil.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.necer.utils;
-
-import android.content.Context;
-import android.graphics.Rect;
-import androidx.core.view.NestedScrollingChild;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import com.necer.R;
-
-public class ViewUtil {
-
- public static View getTargetView(Context context, View view) {
- View targetView = view.findViewWithTag(context.getString(R.string.N_factual_scroll_view));
-
- if (targetView != null && isViewVisible(targetView)) {
- return targetView;
- } else {
- try {
- traverseView(view);
- } catch (ViewUtil.ViewException e) {
- e.printStackTrace();
- return e.getExceptionView();
- }
- }
- return null;
- }
-
-
- private static void traverseView(View view) throws ViewException {
- if (view instanceof NestedScrollingChild && isViewVisible(view)) {
- throw new ViewException(view);
- } else if (view instanceof ViewGroup) {
- int childCount = ((ViewGroup) view).getChildCount();
- for (int i = 0; i < childCount; i++) {
- View childAt = ((ViewGroup) view).getChildAt(i);
- if (childAt instanceof NestedScrollingChild && isViewVisible(childAt)) {
- throw new ViewException(childAt);
- } else {
- traverseView(childAt);
- }
- }
- }
- }
-
- //是否在屏幕上面显示 targetView需要显示并且宽度大于父view宽度的一半
- private static boolean isViewVisible(View view) {
- if (view.getVisibility() != View.VISIBLE) {
- return false;
- }
-
- ViewParent parent = view.getParent();
- if (parent != null && parent instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) parent;
- int width = viewGroup.getWidth();
- Rect rect = new Rect();
- boolean globalVisibleRect = view.getGlobalVisibleRect(rect);
- int visibleWidth = rect.width();
- return globalVisibleRect && visibleWidth >= width / 2;
- }
- return view.getGlobalVisibleRect(new Rect());
- }
-
-
- public static class ViewException extends Throwable {
-
- private View view;
-
- public ViewException(View view) {
- this.view = view;
- }
-
- public View getExceptionView() {
- return view;
- }
- }
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/ChineseDate.kt b/ncalendar/src/main/java/com/necer/utils/hutool/ChineseDate.kt
new file mode 100644
index 00000000..5d27ad3b
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/ChineseDate.kt
@@ -0,0 +1,328 @@
+package com.necer.utils.hutool
+
+import java.time.LocalDate
+
+/**
+ * 农历日期工具,最大支持到2099年,支持:
+ *
+ *
+ * * 通过公历日期构造获取对应农历
+ * * 通过农历日期直接构造
+ *
+ *
+ * @author zjw, looly
+ * @since 5.1.1
+ */
+class ChineseDate {
+
+
+ private val DAY_NAME = arrayOf("一", "二", "三", "四", "五", "六", "七", "八", "九", "十")
+ private val MONTH_NAME = arrayOf("一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二")
+ private val MONTH_NAME_TRADITIONAL = arrayOf("正", "二", "三", "四", "五", "六", "七", "八", "九", "寒", "冬", "腊")
+ private val CHINESE_ZODIACS = arrayOf("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪")
+
+
+ /**
+ * 获得农历年份
+ *
+ * @return 返回农历年份
+ */
+ //农历年
+ val chineseYear: Int
+
+ /**
+ * 获取农历的月,从1开始计数
+ * 此方法返回实际的月序号,如一月是闰月,则一月返回1,润一月返回2
+ *
+ * @return 农历的月
+ * @since 5.2.4
+ */
+ //农历月,润N月这个值就是N+1,其他月按照显示月份赋值
+ val month: Int
+
+ /**
+ * 当前农历月份是否为闰月
+ *
+ * @return 是否为闰月
+ * @since 5.4.2
+ */
+ // 当前月份是否闰月
+ val isLeapMonth: Boolean
+
+ /**
+ * 获取农历的日,从1开始计数
+ *
+ * @return 农历的日,从1开始计数
+ * @since 5.2.4
+ */
+ //农历日
+ val day: Int
+
+ /**
+ * 获取公历的年
+ *
+ * @return 公历年
+ * @since 5.6.1
+ */
+ //公历年
+ val gregorianYear: Int
+
+ /**
+ * 获取公历的月,从1开始计数
+ *
+ * @return 公历月
+ * @since 5.6.1
+ */
+ //公历月,从1开始计数
+ val gregorianMonthBase1: Int
+
+ /**
+ * 获取公历的日
+ *
+ * @return 公历日
+ * @since 5.6.1
+ */
+ //公历日
+ val gregorianDay: Int
+
+
+ /**
+ * 通过公历日期构造
+ *
+ * @param localDate 公历日期
+ * @since 5.7.22
+ */
+ constructor(localDate: LocalDate) {
+ // 公历
+ gregorianYear = localDate.year
+ gregorianMonthBase1 = localDate.monthValue
+ gregorianDay = localDate.dayOfMonth
+
+ // 求出和1900年1月31日相差的天数
+ var offset = (localDate.toEpochDay() - LunarInfo.BASE_DAY).toInt()
+
+ // 计算农历年份
+ // 用offset减去每农历年的天数,计算当天是农历第几天,offset是当年的第几天
+ var daysOfYear: Int
+ var iYear: Int
+ iYear = LunarInfo.BASE_YEAR
+ while (iYear <= LunarInfo.MAX_YEAR) {
+ daysOfYear = LunarInfo.yearDays(iYear)
+ if (offset < daysOfYear) {
+ break
+ }
+ offset -= daysOfYear
+ iYear++
+ }
+ chineseYear = iYear
+ // 计算农历月份
+ val leapMonth = LunarInfo.leapMonth(iYear) // 闰哪个月,1-12
+ // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
+ var month: Int
+ var daysOfMonth: Int
+ var hasLeapMonth = false
+ month = 1
+ while (month < 13) {
+
+ // 闰月,如润的是五月,则5表示五月,6表示润五月
+ if (leapMonth > 0 && month == leapMonth + 1) {
+ daysOfMonth = LunarInfo.leapDays(chineseYear)
+ hasLeapMonth = true
+ } else {
+ // 普通月,当前面的月份存在闰月时,普通月份要-1,递补闰月的数字
+ // 如2月是闰月,此时3月实际是第四个月
+ daysOfMonth = LunarInfo.monthDays(chineseYear, if (hasLeapMonth) month - 1 else month)
+ }
+ if (offset < daysOfMonth) {
+ // offset不足月,结束
+ break
+ }
+ offset -= daysOfMonth
+ month++
+ }
+ isLeapMonth = leapMonth > 0 && month == leapMonth + 1
+ if (hasLeapMonth && false == isLeapMonth) {
+ // 当前月份前有闰月,则月份显示要-1,除非当前月份就是润月
+ month--
+ }
+ this.month = month
+ day = offset + 1
+ }
+
+ /**
+ * 获取公历的月,从0开始计数
+ *
+ * @return 公历月
+ * @since 5.6.1
+ */
+ fun getGregorianMonth(): Int {
+ return gregorianMonthBase1 - 1
+ }
+
+ /**
+ * 获得农历月份(中文,例如二月,十二月,或者润一月)
+ *
+ * @return 返回农历月份
+ */
+ fun getChineseMonth(): String {
+ return getChineseMonth(false)
+ }
+
+ /**
+ * 获得农历月称呼(中文,例如二月,腊月,或者润正月)
+ *
+ * @return 返回农历月份称呼
+ */
+ fun getChineseMonthName(): String {
+ return getChineseMonth(true)
+ }
+
+ /**
+ * 获得农历月份(中文,例如二月,十二月,或者润一月)
+ *
+ * @param isTraditional 是否传统表示,例如一月传统表示为正月
+ * @return 返回农历月份
+ * @since 5.7.18
+ */
+ fun getChineseMonth(isTraditional: Boolean): String {
+ return getChineseMonthName(
+ isLeapMonth,
+ if (isLeapMonth) month - 1 else month, isTraditional
+ )
+ }
+
+ /**
+ * 获得农历日
+ *
+ * @return 获得农历日
+ */
+ fun getChineseDay(): String {
+ val chineseTen = arrayOf("初", "十", "廿", "卅")
+ val n = if (day % 10 == 0) 9 else day % 10 - 1
+ return if (day > 30) {
+ ""
+ } else when (day) {
+ 10 -> "初十"
+ 20 -> "二十"
+ 30 -> "三十"
+ else -> chineseTen[day / 10] + DAY_NAME[n]
+ }
+ }
+
+ /**
+ * 获得农历节日,闰月不计入节日中
+ *
+ * @return 获得农历节日
+ */
+ fun getLunarFestivals(): String? {
+ return LunarFestival.getFestivals(chineseYear, month, day)
+ }
+
+ /**
+ * 获得公历节日
+ */
+ fun getSolarFestivals(): String? {
+ return SolarFestival.getFestivals(gregorianMonthBase1, gregorianDay)
+ }
+
+
+ /**
+ * 获得年份生肖
+ *
+ * @return 获得年份生肖
+ */
+ fun getChineseZodiac(): String? {
+ return getChineseZodiac(chineseYear)
+ }
+
+ /**
+ * 获得年的天干地支
+ *
+ * @return 获得天干地支
+ */
+ fun getCyclical(): String {
+ return GanZhi.getGanzhiOfYear(chineseYear)
+ }
+
+ /**
+ * 干支纪年信息
+ *
+ * @return 获得天干地支的年月日信息
+ */
+ fun getCyclicalYMD(): String? {
+ return if (gregorianYear >= LunarInfo.BASE_YEAR && gregorianMonthBase1 > 0 && gregorianDay > 0) {
+ cyclicalm(gregorianYear, gregorianMonthBase1, gregorianDay)
+ } else null
+ }
+
+
+ /**
+ * 获得节气
+ *
+ * @return 获得节气
+ * @since 5.6.3
+ */
+ fun getTerm(): String {
+ return SolarTerms.getTerm(gregorianYear, gregorianMonthBase1, gregorianDay)
+ }
+
+ /**
+ * 转换为标准的日期格式来表示农历日期,例如2020-01-13
+ * 如果存在闰月,显示闰月月份,如润二月显示2
+ *
+ * @return 标准的日期格式
+ * @since 5.2.4
+ */
+ fun toStringNormal(): String {
+ return String.format(
+ "%04d-%02d-%02d", chineseYear,
+ if (isLeapMonth) month - 1 else month, day
+ )
+ }
+
+ override fun toString(): String {
+ return String.format("%s%s年 %s%s", getCyclical(), getChineseZodiac(), getChineseMonthName(), getChineseDay())
+ }
+ // ------------------------------------------------------- private method start
+ /**
+ * 这里同步处理年月日的天干地支信息
+ *
+ * @param year 公历年
+ * @param month 公历月,从1开始
+ * @param day 公历日
+ * @return 天干地支信息
+ */
+ private fun cyclicalm(year: Int, month: Int, day: Int): String {
+ return GanZhi.getGanzhiOfYear(chineseYear) + "年" +
+ GanZhi.getGanzhiOfMonth(year, month, day) + "月" +
+ GanZhi.getGanzhiOfDay(year, month, day) + "日"
+
+ }
+
+ /**
+ * 获得农历月称呼
+ * 当为传统表示时,表示为二月,腊月,或者润正月等
+ * 当为非传统表示时,二月,十二月,或者润一月等
+ *
+ * @param isLeapMonth 是否闰月
+ * @param month 月份,从1开始,如果是闰月,应传入需要显示的月份
+ * @param isTraditional 是否传统表示,例如一月传统表示为正月
+ * @return 返回农历月份称呼
+ */
+ private fun getChineseMonthName(isLeapMonth: Boolean, month: Int, isTraditional: Boolean): String {
+ return (if (isLeapMonth) "闰" else "") + (if (isTraditional) MONTH_NAME_TRADITIONAL else MONTH_NAME)[month - 1] + "月"
+ }
+
+
+ /**
+ * 计算生肖,只计算1900年后的日期
+ *
+ * @param year 农历年
+ * @return 生肖名
+ */
+ private fun getChineseZodiac(year: Int): String? {
+ return if (year < 1900) {
+ null
+ } else CHINESE_ZODIACS[(year - 1900) % CHINESE_ZODIACS.size]
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/GanZhi.kt b/ncalendar/src/main/java/com/necer/utils/hutool/GanZhi.kt
new file mode 100644
index 00000000..3f8cd5ce
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/GanZhi.kt
@@ -0,0 +1,80 @@
+package com.necer.utils.hutool
+
+import java.time.LocalDate
+
+/**
+ * 天干地支类
+ * 天干地支,简称为干支
+ *
+ * @author looly
+ * @since 5.4.1
+ */
+object GanZhi {
+ /**
+ * 十天干:甲(jiǎ)、乙(yǐ)、丙(bǐng)、丁(dīng)、戊(wù)、己(jǐ)、庚(gēng)、辛(xīn)、壬(rén)、癸(guǐ)
+ * 十二地支:子(zǐ)、丑(chǒu)、寅(yín)、卯(mǎo)、辰(chén)、巳(sì)、午(wǔ)、未(wèi)、申(shēn)、酉(yǒu)、戌(xū)、亥(hài)
+ * 十二地支对应十二生肖:子-鼠,丑-牛,寅-虎,卯-兔,辰-龙,巳-蛇, 午-马,未-羊,申-猴,酉-鸡,戌-狗,亥-猪
+ *
+ * @see [天干地支:简称,干支](https://baike.baidu.com/item/%E5%A4%A9%E5%B9%B2%E5%9C%B0%E6%94%AF/278140)
+ */
+ private val GAN = arrayOf("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸")
+ private val ZHI = arrayOf("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥")
+
+ /**
+ * 传入 月日的offset 传回干支, 0=甲子
+ *
+ * @param num 月日的offset
+ * @return 干支
+ */
+ fun cyclicalm(num: Int): String {
+ return GAN[num % 10] + ZHI[num % 12]
+ }
+
+ /**
+ * 传入年传回干支
+ *
+ * @param year 农历年
+ * @return 干支
+ * @since 5.4.7
+ */
+ fun getGanzhiOfYear(year: Int): String {
+ // 1864年(1900 - 36)是甲子年,用于计算基准的干支年
+ return cyclicalm(year - LunarInfo.BASE_YEAR + 36)
+ }
+
+ /**
+ * 获取干支月
+ *
+ * @param year 公历年
+ * @param month 公历月,从1开始
+ * @param day 公历日
+ * @return 干支月
+ * @since 5.4.7
+ */
+ fun getGanzhiOfMonth(year: Int, month: Int, day: Int): String {
+ //返回当月「节」为几日开始
+ val firstNode = SolarTerms.getTerm(year, month * 2 - 1)
+ // 依据12节气修正干支月
+ var monthOffset = (year - LunarInfo.BASE_YEAR) * 12 + month + 11
+ if (day >= firstNode) {
+ monthOffset++
+ }
+ return cyclicalm(monthOffset)
+ }
+
+ /**
+ * 获取干支日
+ *
+ * @param year 公历年
+ * @param month 公历月,从1开始
+ * @param day 公历日
+ * @return 干支
+ * @since 5.4.7
+ */
+ fun getGanzhiOfDay(year: Int, month: Int, day: Int): String {
+ // 与1970-01-01相差天数,不包括当天
+ val days = LocalDate.of(year, month, day).toEpochDay() - 1
+ //1899-12-21是农历1899年腊月甲子日 41:相差1900-01-31有41天
+ return cyclicalm((days - LunarInfo.BASE_DAY + 41).toInt())
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/LunarFestival.kt b/ncalendar/src/main/java/com/necer/utils/hutool/LunarFestival.kt
new file mode 100644
index 00000000..f8a1c712
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/LunarFestival.kt
@@ -0,0 +1,110 @@
+package com.necer.utils.hutool
+
+/**
+ * 节假日(农历)封装
+ *
+ * @author looly
+ * @since 5.4.1
+ */
+object LunarFestival {
+ //农历节日 *表示放假日
+ // 来自:https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E4%BC%A0%E7%BB%9F%E8%8A%82%E6%97%A5/396100
+ private val L_FTV: HashMap, String> = HashMap()
+
+ init {
+ // 节日
+ L_FTV[Pair(1, 1)] = "春节"
+// L_FTV[Pair(1, 2)] = "犬日"
+// L_FTV[Pair(1, 3)] = "猪日"
+// L_FTV[Pair(1, 4)] = "羊日"
+// L_FTV[Pair(1, 5)] = "牛日 破五日"
+// L_FTV[Pair(1, 6)] = "马日 送穷日"
+// L_FTV[Pair(1, 7)] = "人日 人胜节"
+// L_FTV[Pair(1, 8)] = "谷日 八仙日"
+// L_FTV[Pair(1, 9)] = "天日 九皇会"
+// L_FTV[Pair(1, 10)] = "地日 石头生日"
+// L_FTV[Pair(1, 12)] = "火日 老鼠娶媳妇日"
+// L_FTV[Pair(1, 13)] = "上(试)灯日 关公升天日"
+ L_FTV[Pair(1, 15)] = "元宵节"
+// L_FTV[Pair(1, 18)] = "落灯日"
+
+ // 二月
+// L_FTV[Pair(2, 1)] = "中和节 太阳生日"
+// L_FTV[Pair(2, 2)] = "龙抬头"
+// L_FTV[Pair(2, 12)] = "花朝节"
+// L_FTV[Pair(2, 19)] = "观世音圣诞"
+
+ // 三月
+// L_FTV[Pair(3, 3)] = "上巳节"
+
+ // 四月
+// L_FTV[Pair(4, 1)] = "祭雹神"
+// L_FTV[Pair(4, 4)] = "文殊菩萨诞辰"
+// L_FTV[Pair(4, 8)] = "佛诞节"
+
+ // 五月
+ L_FTV[Pair(5, 5)] = "端午节"
+
+ // 六月
+// L_FTV[Pair(6, 6)] = "晒衣节 姑姑节"
+// L_FTV[Pair(6, 6)] = "天贶节"
+// L_FTV[Pair(6, 24)] = "彝族火把节"
+
+ // 七月
+ L_FTV[Pair(7, 7)] = "七夕"
+// L_FTV[Pair(7, 14)] = "鬼节(南方)"
+ L_FTV[Pair(7, 15)] = "中元节"
+// L_FTV[Pair(7, 15)] = "盂兰盆节 中元节"
+// L_FTV[Pair(7, 30)] = "地藏节"
+
+ // 八月
+ L_FTV[Pair(8, 15)] = "中秋节"
+
+ // 九月
+ L_FTV[Pair(9, 9)] = "重阳节"
+
+ // 十月
+// L_FTV[Pair(10, 1)] = "祭祖节"
+ L_FTV[Pair(10, 15)] = "下元节"
+
+ // 十一月
+// L_FTV[Pair(11, 17)] = "阿弥陀佛圣诞"
+
+ // 腊月
+ L_FTV[Pair(12, 8)] = "腊八节"
+// L_FTV[Pair(12, 16)] = "尾牙"
+ L_FTV[Pair(12, 23)] = "小年"
+ L_FTV[Pair(12, 30)] = "除夕"
+ }
+
+ /**
+ * 获得节日列表
+ *
+ * @param year 年
+ * @param month 月
+ * @param day 日
+ * @return 获得农历节日
+ * @since 5.4.5
+ */
+ fun getFestivals(year: Int, month: Int, day: Int): String? {
+ // 春节判断,如果12月是小月,则29为除夕,否则30为除夕
+ var day = day
+ if (12 == month && 29 == day) {
+ if (29 == LunarInfo.monthDays(year, month)) {
+ day++
+ }
+ }
+ return getFestivals(month, day)
+ }
+
+ /**
+ * 获得节日列表,此方法无法判断月是否为大月或小月
+ *
+ * @param month 月
+ * @param day 日
+ * @return 获得农历节日
+ */
+ fun getFestivals(month: Int, day: Int): String? {
+ return L_FTV[Pair(month, day)]
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/LunarInfo.kt b/ncalendar/src/main/java/com/necer/utils/hutool/LunarInfo.kt
new file mode 100644
index 00000000..bf87db3b
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/LunarInfo.kt
@@ -0,0 +1,117 @@
+package com.necer.utils.hutool
+
+import java.time.LocalDate
+
+/**
+ * 阴历(农历)信息
+ *
+ * @author looly
+ * @since 5.4.1
+ */
+object LunarInfo {
+ /**
+ * 1900年
+ */
+ const val BASE_YEAR = 1900
+
+ /**
+ * 1900-01-31,农历正月初一
+ */
+ val BASE_DAY = LocalDate.of(BASE_YEAR, 1, 31).toEpochDay()
+
+ /**
+ * 此表来自:[https://github.com/jjonline/calendar.js/blob/master/calendar.js](https://github.com/jjonline/calendar.js/blob/master/calendar.js)
+ * 农历表示:
+ * 1. 表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
+ * 2-4.为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
+ * 5. 表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
+ */
+ private val LUNAR_CODE = longArrayOf(
+ 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909
+ 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919
+ 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929
+ 0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939
+ 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949
+ 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
+ 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969
+ 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979
+ 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989
+ 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999
+ 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
+ 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019
+ 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029
+ 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039
+ 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049
+ 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
+ 0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
+ 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
+ 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
+ 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252
+ )
+
+ // 支持的最大年限
+ val MAX_YEAR = BASE_YEAR + LUNAR_CODE.size - 1
+
+ /**
+ * 传回农历 y年的总天数
+ *
+ * @param y 年
+ * @return 总天数
+ */
+ fun yearDays(y: Int): Int {
+ var i: Int
+ var sum = 348
+ i = 0x8000
+ while (i > 0x8) {
+ if (getCode(y) and i.toLong() != 0L) {
+ sum += 1
+ }
+ i = i shr 1
+ }
+ return sum + leapDays(y)
+ }
+
+ /**
+ * 传回农历 y年闰月的天数,如果本年无闰月,返回0,区分大小月
+ *
+ * @param y 农历年
+ * @return 闰月的天数
+ */
+ fun leapDays(y: Int): Int {
+ return if (leapMonth(y) != 0) {
+ if (getCode(y) and 0x10000L != 0L) 30 else 29
+ } else 0
+ }
+
+ /**
+ * 传回农历 y年m月的总天数,区分大小月
+ *
+ * @param y 年
+ * @param m 月
+ * @return 总天数
+ */
+ fun monthDays(y: Int, m: Int): Int {
+ return if (getCode(y) and (0x10000 shr m).toLong() == 0L) 29 else 30
+ }
+
+ /**
+ * 传回农历 y年闰哪个月 1-12 , 没闰传回 0
+ * 此方法会返回润N月中的N,如二月、闰二月都返回2
+ *
+ * @param y 年
+ * @return 润的月, 没闰传回 0
+ */
+ fun leapMonth(y: Int): Int {
+ return (getCode(y) and 0xfL).toInt()
+ }
+
+ /**
+ * 获取对应年的农历信息
+ *
+ * @param year 年
+ * @return 农历信息
+ */
+ private fun getCode(year: Int): Long {
+ return LUNAR_CODE[year - BASE_YEAR]
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/SolarFestival.kt b/ncalendar/src/main/java/com/necer/utils/hutool/SolarFestival.kt
new file mode 100644
index 00000000..1656d425
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/SolarFestival.kt
@@ -0,0 +1,58 @@
+package com.necer.utils.hutool
+
+/**
+ * 节假日(公历)封装
+ *
+ */
+object SolarFestival {
+
+ private val S_FTV: HashMap, String> = HashMap()
+
+ init {
+ // 节日
+ S_FTV[Pair(1, 1)] = "元旦"
+
+ // 二月
+ S_FTV[Pair(2, 14)] = "情人节"
+
+ // 三月
+ S_FTV[Pair(3, 8)] = "妇女节"
+ S_FTV[Pair(3, 12)] = "植树节"
+ S_FTV[Pair(3, 15)] = "消费者"
+
+ // 四月
+ S_FTV[Pair(4, 1)] = "愚人节"
+
+ // 五月
+ S_FTV[Pair(5, 1)] = "劳动节"
+ S_FTV[Pair(5, 4)] = "青年节"
+
+ // 六月
+ S_FTV[Pair(6, 1)] = "儿童节"
+
+ // 七月
+ S_FTV[Pair(7, 1)] = "建党节"
+
+ // 八月
+ S_FTV[Pair(8, 1)] = "建军节"
+
+ // 九月
+ S_FTV[Pair(9, 10)] = "教师节"
+
+ // 十月
+ S_FTV[Pair(10, 1)] = "国庆节"
+ }
+
+
+
+ /**
+ * 获得节日
+ *
+ * @param month 月
+ * @param day 日
+ * @return 获得公历节日
+ */
+ fun getFestivals(month: Int, day: Int): String? {
+ return S_FTV[Pair(month, day)]
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/utils/hutool/SolarTerms.kt b/ncalendar/src/main/java/com/necer/utils/hutool/SolarTerms.kt
new file mode 100644
index 00000000..dfae7dee
--- /dev/null
+++ b/ncalendar/src/main/java/com/necer/utils/hutool/SolarTerms.kt
@@ -0,0 +1,176 @@
+package com.necer.utils.hutool
+
+import java.time.LocalDate
+
+/**
+ * 24节气相关信息
+ *
+ * @author looly, zak
+ * @since 5.4.1
+ */
+object SolarTerms {
+ /**
+ * 1900-2100各年的24节气日期速查表
+ * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js
+ */
+ private val S_TERM_INFO = arrayOf(
+ "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf97c3598082c95f8c965cc920f",
+ "97bd0b06bdb0722c965ce1cfcc920f", "b027097bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+ "97bcf97c359801ec95f8c965cc920f", "97bd0b06bdb0722c965ce1cfcc920f", "b027097bd097c36b0b6fc9274c91aa",
+ "97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f", "97bd0b06bdb0722c965ce1cfcc920f",
+ "b027097bd097c36b0b6fc9274c91aa", "9778397bd19801ec9210c965cc920e", "97b6b97bd19801ec95f8c965cc920f",
+ "97bd09801d98082c95f8e1cfcc920f", "97bd097bd097c36b0b6fc9210c8dc2", "9778397bd197c36c9210c9274c91aa",
+ "97b6b97bd19801ec95f8c965cc920e", "97bd09801d98082c95f8e1cfcc920f", "97bd097bd097c36b0b6fc9210c8dc2",
+ "9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec95f8c965cc920e", "97bcf97c3598082c95f8e1cfcc920f",
+ "97bd097bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+ "97bcf97c3598082c95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b97bd19801ec9210c965cc920e", "97bcf97c3598082c95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722",
+ "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f",
+ "97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+ "97bcf97c359801ec95f8c965cc920f", "97bd097bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b97bd19801ec9210c965cc920e", "97bcf97c359801ec95f8c965cc920f", "97bd097bd07f595b0b6fc920fb0722",
+ "9778397bd097c36b0b6fc9210c8dc2", "9778397bd19801ec9210c9274c920e", "97b6b97bd19801ec95f8c965cc920f",
+ "97bd07f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c920e",
+ "97b6b97bd19801ec95f8c965cc920f", "97bd07f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2",
+ "9778397bd097c36c9210c9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bd07f1487f595b0b0bc920fb0722",
+ "7f0e397bd097c36b0b6fc9210c8dc2", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+ "97bcf7f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b97bd19801ec9210c965cc920e", "97bcf7f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+ "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e", "97bcf7f1487f531b0b0bb0b6fb0722",
+ "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b97bd19801ec9210c965cc920e",
+ "97bcf7f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b97bd19801ec9210c9274c920e", "97bcf7f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+ "9778397bd097c36b0b6fc9210c91aa", "97b6b97bd197c36c9210c9274c920e", "97bcf7f0e47f531b0b0bb0b6fb0722",
+ "7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9210c8dc2", "9778397bd097c36c9210c9274c920e",
+ "97b6b7f0e47f531b0723b0b6fb0722", "7f0e37f5307f595b0b0bc920fb0722", "7f0e397bd097c36b0b6fc9210c8dc2",
+ "9778397bd097c36b0b70c9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721", "7f0e37f1487f595b0b0bb0b6fb0722",
+ "7f0e397bd097c35b0b6fc9210c8dc2", "9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721",
+ "7f0e27f1487f595b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+ "9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+ "7f0e397bd097c35b0b6fc920fb0722", "9778397bd097c36b0b6fc9274c91aa", "97b6b7f0e47f531b0723b0b6fb0721",
+ "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9274c91aa",
+ "97b6b7f0e47f531b0723b0787b0721", "7f0e27f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+ "9778397bd097c36b0b6fc9210c91aa", "97b6b7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+ "7f0e397bd07f595b0b0bc920fb0722", "9778397bd097c36b0b6fc9210c8dc2", "977837f0e37f149b0723b0787b0721",
+ "7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f5307f595b0b0bc920fb0722", "7f0e397bd097c35b0b6fc9210c8dc2",
+ "977837f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e37f1487f595b0b0bb0b6fb0722",
+ "7f0e397bd097c35b0b6fc9210c8dc2", "977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+ "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722", "977837f0e37f14998082b0787b06bd",
+ "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd097c35b0b6fc920fb0722",
+ "977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+ "7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+ "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14998082b0787b06bd",
+ "7f07e7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0b0bb0b6fb0722", "7f0e397bd07f595b0b0bc920fb0722",
+ "977837f0e37f14998082b0723b06bd", "7f07e7f0e37f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+ "7f0e397bd07f595b0b0bc920fb0722", "977837f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b0721",
+ "7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f1487f595b0b0bb0b6fb0722", "7f0e37f0e37f14898082b0723b02d5",
+ "7ec967f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0722", "7f0e37f1487f531b0b0bb0b6fb0722",
+ "7f0e37f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+ "7f0e37f1487f531b0b0bb0b6fb0722", "7f0e37f0e37f14898082b072297c35", "7ec967f0e37f14998082b0787b06bd",
+ "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e37f0e37f14898082b072297c35",
+ "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722",
+ "7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f149b0723b0787b0721",
+ "7f0e27f1487f531b0b0bb0b6fb0722", "7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14998082b0723b06bd",
+ "7f07e7f0e47f149b0723b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722", "7f0e37f0e366aa89801eb072297c35",
+ "7ec967f0e37f14998082b0723b06bd", "7f07e7f0e37f14998083b0787b0721", "7f0e27f0e47f531b0723b0b6fb0722",
+ "7f0e37f0e366aa89801eb072297c35", "7ec967f0e37f14898082b0723b02d5", "7f07e7f0e37f14998082b0787b0721",
+ "7f07e7f0e47f531b0723b0b6fb0722", "7f0e36665b66aa89801e9808297c35", "665f67f0e37f14898082b0723b02d5",
+ "7ec967f0e37f14998082b0787b0721", "7f07e7f0e47f531b0723b0b6fb0722", "7f0e36665b66a449801e9808297c35",
+ "665f67f0e37f14898082b0723b02d5", "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721",
+ "7f0e36665b66a449801e9808297c35", "665f67f0e37f14898082b072297c35", "7ec967f0e37f14998082b0787b06bd",
+ "7f07e7f0e47f531b0723b0b6fb0721", "7f0e26665b66a449801e9808297c35", "665f67f0e37f1489801eb072297c35",
+ "7ec967f0e37f14998082b0787b06bd", "7f07e7f0e47f531b0723b0b6fb0721", "7f0e27f1487f531b0b0bb0b6fb0722"
+ )
+
+ /**
+ * 24节气
+ */
+ private val TERMS = arrayOf(
+ "小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
+ "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
+ "小暑", "大暑", "立秋", "处暑", "白露", "秋分",
+ "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
+ )
+
+ /**
+ * 传入公历y年获得该年第n个节气的公历日期
+ *
+ * @param y 公历年(1900-2100)
+ * @param n 二十四节气中的第几个节气(1~24);从n=1(小寒)算起
+ * @return getTerm(1987,3) -》4;意即1987年2月4日立春
+ */
+ fun getTerm(y: Int, n: Int): Int {
+ if (y < 1900 || y > 2100) {
+ return -1
+ }
+ if (n < 1 || n > 24) {
+ return -1
+ }
+ val _table = S_TERM_INFO[y - 1900]
+ val _info = arrayOfNulls(6)
+ for (i in 0..5) {
+ _info[i] = _table.substring(i * 5, 5 * (i + 1)).toInt(16)
+ }
+ val _calday = arrayOfNulls(24)
+ for (i in 0..5) {
+ _calday[4 * i] = _info[i].toString().substring(0, 1)
+ _calday[4 * i + 1] = _info[i].toString().substring(1, 3)
+ _calday[4 * i + 2] = _info[i].toString().substring(3, 4)
+ _calday[4 * i + 3] = _info[i].toString().substring(4, 6)
+ }
+
+ return (_calday[n - 1])!!.toInt()
+ }
+
+ /**
+ * 根据日期获取节气
+ * @param localDate 日期
+ * @return 返回指定日期所处的节气,若不是一个节气则返回空字符串
+ */
+ fun getTerm(localDate: LocalDate): String {
+ return getTermInternal(localDate.year, localDate.monthValue, localDate.dayOfMonth)
+ }
+
+ /**
+ * 根据年月日获取节气
+ * @param year 公历年
+ * @param mouth 公历月,从1开始
+ * @param day 公历日,从1开始
+ * @return 返回指定年月日所处的节气,若不是一个节气则返回空字符串
+ */
+ fun getTerm(year: Int, mouth: Int, day: Int): String {
+ return getTerm(LocalDate.of(year, mouth, day))
+ }
+
+ /**
+ * 根据年月日获取节气, 内部方法,不对月和日做有效校验
+ * @param year 公历年
+ * @param mouth 公历月,从1开始
+ * @param day 公历日,从1开始
+ * @return 返回指定年月日所处的节气,若不是一个节气则返回空字符串
+ */
+ private fun getTermInternal(year: Int, mouth: Int, day: Int): String {
+ require(!(year < 1900 || year > 2100)) { "只支持1900-2100之间的日期获取节气" }
+ val termTable = S_TERM_INFO[year - 1900]
+
+ // 节气速查表中每5个字符含有4个节气,通过月份直接计算偏移
+ val segment = (mouth + 1) / 2 - 1
+ val termInfo = termTable.substring(segment * 5, (segment + 1) * 5).toInt(16)
+ val termInfoStr = termInfo.toString()
+ val segmentTable = arrayOfNulls(4)
+ segmentTable[0] = termInfoStr.substring(0, 1)
+ segmentTable[1] = termInfoStr.substring(1, 3)
+ segmentTable[2] = termInfoStr.substring(3, 4)
+ segmentTable[3] = termInfoStr.substring(4, 6)
+
+ // 奇数月份的节气在前2个,偶数月份的节气在后两个
+ val segmentOffset = if (mouth and 1 == 1) 0 else 2
+ if (day == segmentTable[segmentOffset]!!.toInt()) {
+ return TERMS[segment * 4 + segmentOffset]
+ }
+ return if (day == segmentTable[segmentOffset + 1]!!.toInt()) {
+ TERMS[segment * 4 + segmentOffset + 1]
+ } else ""
+ }
+}
\ No newline at end of file
diff --git a/ncalendar/src/main/java/com/necer/view/CalendarView.java b/ncalendar/src/main/java/com/necer/view/CalendarView.java
deleted file mode 100644
index d2b44a15..00000000
--- a/ncalendar/src/main/java/com/necer/view/CalendarView.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package com.necer.view;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.necer.R;
-import com.necer.calendar.BaseCalendar;
-import com.necer.drawable.TextDrawable;
-import com.necer.enumeration.CalendarType;
-import com.necer.helper.CalendarHelper;
-import com.necer.painter.CalendarBackground;
-import com.necer.painter.CalendarPainter;
-import com.necer.utils.CalendarUtil;
-import com.necer.utils.DrawableUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-/**
- * @author necer
- * @date 2018/9/11
- * qq群:127278900
- */
-public class CalendarView extends View implements ICalendarView {
-
-
- private CalendarHelper mCalendarHelper;
-
- private int mCurrentDistance = -1;//折叠日历滑动当前的距离 为区分初始化为0和滑动结束为0,故此处初始化为-1
-
- protected List mDateList;
-
- public CalendarView(Context context, BaseCalendar calendar, LocalDate initialDate, CalendarType calendarType) {
- super(context);
- mCalendarHelper = new CalendarHelper(calendar, initialDate, calendarType);
- mDateList = mCalendarHelper.getDateList();
- }
-
-
- @Override
- protected void onDraw(Canvas canvas) {
-
- //绘制背景
- CalendarBackground calendarBackground = mCalendarHelper.getCalendarBackground();
- drawBackground(canvas, calendarBackground);
-
- //绘制日期
- CalendarPainter calendarPainter = mCalendarHelper.getCalendarPainter();
- drawDates(canvas, calendarPainter);
- }
-
- //绘制背景
- private void drawBackground(Canvas canvas, CalendarBackground calendarBackground) {
- int currentDistance = mCurrentDistance == -1 ? mCalendarHelper.getInitialDistance() : mCurrentDistance;
- Drawable backgroundDrawable = calendarBackground.getBackgroundDrawable(mCalendarHelper.getMiddleLocalDate(), currentDistance, mCalendarHelper.getCalendarHeight());
- Rect backgroundRectF = mCalendarHelper.getBackgroundRectF();
- backgroundDrawable.setBounds(DrawableUtil.getDrawableBounds(backgroundRectF.centerX(), backgroundRectF.centerY(), backgroundDrawable));
- backgroundDrawable.draw(canvas);
- }
-
- //绘制日期
- private void drawDates(Canvas canvas, CalendarPainter calendarPainter) {
-
- for (int i = 0; i < mCalendarHelper.getLineNum(); i++) {
- for (int j = 0; j < 7; j++) {
- RectF rectF = mCalendarHelper.getRealRectF(i, j);
- int index = i * 7 + j;
- LocalDate localDate = mDateList.get(index);
- if (mCalendarHelper.isAvailableDate(localDate)) { //可用的日期
- if (mCalendarHelper.isCurrentMonthOrWeek(localDate)) { //当月日期
- if (CalendarUtil.isToday(localDate)) { //当天
- calendarPainter.onDrawToday(canvas, rectF, localDate, mCalendarHelper.getAllSelectListDate());
- } else { //非当天的当月日期
- calendarPainter.onDrawCurrentMonthOrWeek(canvas, rectF, localDate, mCalendarHelper.getAllSelectListDate());
- }
- } else { //上下月日期
- calendarPainter.onDrawLastOrNextMonth(canvas, rectF, localDate, mCalendarHelper.getAllSelectListDate());
- }
- } else { //不可用日期
- calendarPainter.onDrawDisableDate(canvas, rectF, localDate);
- }
- }
- }
- }
-
-
-
- @Override
- public LocalDate getPagerInitialDate() {
- return mCalendarHelper.getPagerInitialDate();
- }
-
- @Override
- public LocalDate getMiddleLocalDate() {
- return mCalendarHelper.getMiddleLocalDate();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return mCalendarHelper.onTouchEvent(event);
- }
-
- @Override
- public int getDistanceFromTop(LocalDate localDate) {
- return mCalendarHelper.getDistanceFromTop(localDate);
- }
-
-
- @Override
- public LocalDate getPivotDate() {
- return mCalendarHelper.getPivotDate();
- }
-
- @Override
- public int getPivotDistanceFromTop() {
- return mCalendarHelper.getPivotDistanceFromTop();
- }
-
- @Override
- public List getCurrPagerCheckDateList() {
- return mCalendarHelper.getCurrentSelectDateList();
- }
-
- @Override
- public void updateSlideDistance(int currentDistance) {
- this.mCurrentDistance = currentDistance;
- invalidate();
- }
-
- @Override
- public List getCurrPagerDateList() {
- return mCalendarHelper.getCurrentDateList();
- }
-
- @Override
- public void notifyCalendarView() {
- invalidate();
- }
-
- //周或者月的第一天
- @Override
- public LocalDate getCurrPagerFirstDate() {
- return mCalendarHelper.getCurrPagerFirstDate();
- }
-
- @Override
- public CalendarType getCalendarType() {
- return mCalendarHelper.getCalendarType();
- }
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/view/CalendarView2.java b/ncalendar/src/main/java/com/necer/view/CalendarView2.java
deleted file mode 100644
index a9d0b099..00000000
--- a/ncalendar/src/main/java/com/necer/view/CalendarView2.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package com.necer.view;
-
-import android.content.Context;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.FrameLayout;
-import android.widget.GridView;
-import android.widget.ListAdapter;
-
-import com.necer.adapter.GridCalendarAdapter;
-import com.necer.calendar.BaseCalendar;
-import com.necer.enumeration.CalendarType;
-import com.necer.helper.CalendarHelper;
-import com.necer.painter.CalendarAdapter;
-import com.necer.painter.CalendarBackground;
-import com.necer.utils.CalendarUtil;
-import com.necer.utils.DrawableUtil;
-
-import org.joda.time.LocalDate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 适配器构造的日历页面
- */
-public class CalendarView2 extends GridView implements ICalendarView {
-
- private CalendarHelper mCalendarHelper;
- private CalendarAdapter mCalendarAdapter;
- private List mDateList;
- private int mCurrentDistance = -1;
- private BaseAdapter gridViewAdapter;
-
-
- public CalendarView2(Context context, BaseCalendar calendar, LocalDate initialDate, CalendarType calendarType) {
- super(context);
- setWillNotDraw(false);
- setNumColumns(7);
-
- mCalendarHelper = new CalendarHelper(calendar, initialDate, calendarType);
- mCalendarAdapter = mCalendarHelper.getCalendarAdapter();
- mDateList = mCalendarHelper.getDateList();
-
- float height = mCalendarHelper.getCalendarHeight();
- float rectHeight5 = height / 5;
- float rectHeight6 = (height / 5) * 4 / 5;
-
- if ((mCalendarHelper.getLineNum()) == 6) {
- int padding = (int) ((rectHeight5 - rectHeight6) / 2);
- setPadding(0, padding, 0, padding);
- }
-
- List viewList = new ArrayList<>();
- for (int i = 0; i < mDateList.size(); i++) {
- View calendarItem = mCalendarAdapter.getCalendarItemView(context);
- viewList.add(calendarItem);
- }
-
- gridViewAdapter = new GridCalendarAdapter(viewList);
- setAdapter(gridViewAdapter);
-
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- //绘制背景
- CalendarBackground calendarBackground = mCalendarHelper.getCalendarBackground();
- drawBackground(canvas, calendarBackground);
-
- }
-
- //绘制背景
- private void drawBackground(Canvas canvas, CalendarBackground calendarBackground) {
- int currentDistance = mCurrentDistance == -1 ? mCalendarHelper.getInitialDistance() : mCurrentDistance;
- Drawable backgroundDrawable = calendarBackground.getBackgroundDrawable(mCalendarHelper.getMiddleLocalDate(), currentDistance, mCalendarHelper.getCalendarHeight());
- Rect backgroundRectF = mCalendarHelper.getBackgroundRectF();
- backgroundDrawable.setBounds(DrawableUtil.getDrawableBounds(backgroundRectF.centerX(), backgroundRectF.centerY(), backgroundDrawable));
- backgroundDrawable.draw(canvas);
- }
-
- //刷新view
- public void bindView(int position,View itemView) {
- LocalDate localDate = mDateList.get(position);
- if (mCalendarHelper.isAvailableDate(localDate)) {
- if (mCalendarHelper.isCurrentMonthOrWeek(localDate)) { //当月日期
- if (CalendarUtil.isToday(localDate)) { //当天
- mCalendarAdapter.onBindToadyView(itemView, localDate, mCalendarHelper.getAllSelectListDate());
- } else { //不是当天的当月其他日期
- mCalendarAdapter.onBindCurrentMonthOrWeekView(itemView, localDate, mCalendarHelper.getAllSelectListDate());
- }
- } else { //不是当月的日期
- mCalendarAdapter.onBindLastOrNextMonthView(itemView, localDate, mCalendarHelper.getAllSelectListDate());
- }
- } else { //日期区间之外的日期
- mCalendarAdapter.onBindDisableDateView(itemView, localDate);
- }
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- mCalendarHelper.resetRectFSize();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return mCalendarHelper.onTouchEvent(event);
- }
-
- @Override
- public LocalDate getPagerInitialDate() {
- return mCalendarHelper.getPagerInitialDate();
- }
-
- @Override
- public LocalDate getMiddleLocalDate() {
- return mCalendarHelper.getMiddleLocalDate();
- }
-
- @Override
- public int getDistanceFromTop(LocalDate localDate) {
- return mCalendarHelper.getDistanceFromTop(localDate);
- }
-
- @Override
- public LocalDate getPivotDate() {
- return mCalendarHelper.getPivotDate();
- }
-
- @Override
- public int getPivotDistanceFromTop() {
- return mCalendarHelper.getPivotDistanceFromTop();
- }
-
- @Override
- public List getCurrPagerCheckDateList() {
- return mCalendarHelper.getCurrentSelectDateList();
- }
-
- @Override
- public void updateSlideDistance(int currentDistance) {
- this.mCurrentDistance = currentDistance;
- invalidate();
- }
-
- @Override
- public List getCurrPagerDateList() {
- return mCalendarHelper.getCurrentDateList();
- }
-
- @Override
- public void notifyCalendarView() {
- gridViewAdapter.notifyDataSetChanged();
- }
-
- //周或者月的第一天
- @Override
- public LocalDate getCurrPagerFirstDate() {
- return mCalendarHelper.getCurrPagerFirstDate();
- }
-
- @Override
- public CalendarType getCalendarType() {
- return mCalendarHelper.getCalendarType();
- }
-
-
-}
diff --git a/ncalendar/src/main/java/com/necer/view/ICalendarView.java b/ncalendar/src/main/java/com/necer/view/ICalendarView.java
deleted file mode 100644
index 01a4e76c..00000000
--- a/ncalendar/src/main/java/com/necer/view/ICalendarView.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.necer.view;
-
-import com.necer.enumeration.CalendarType;
-import com.necer.painter.CalendarBackground;
-
-import org.joda.time.LocalDate;
-
-import java.util.List;
-
-/**
- * @author necer
- */
-public interface ICalendarView {
-
-
- /**
- * 获取当前页面的初始化日期
- *
- * @return
- */
- LocalDate getPagerInitialDate();
-
- /**
- * 获取中间的日期,周日历以中间的日期判断当前页面的年和月
- *
- * @return
- */
- LocalDate getMiddleLocalDate();
-
-
- /**
- * 选中的日期到顶部的距离
- *
- * @return
- */
- int getDistanceFromTop(LocalDate localDate);
-
-
- /**
- * 获取折叠的中心点 如果有当前页面有选中 返回选中的日期,如果没有选中看是否包含今天,如果没有就返回当前页面第一个日期
- *
- * @return
- */
- LocalDate getPivotDate();
-
- /**
- * 获取中心点到顶部的距离
- *
- * @return
- */
- int getPivotDistanceFromTop();
-
-
- /**
- * 获取当前页面选中的日期
- *
- * @return
- */
- List getCurrPagerCheckDateList();
-
- /**
- * 月周切换时滑动的距离
- *
- * @param currentDistance
- */
- void updateSlideDistance(int currentDistance);
-
-
- /**
- * 获取当前页面的日期
- *
- * @return
- */
- List getCurrPagerDateList();
-
-
- /**
- * 刷新当前页面
- */
- void notifyCalendarView();
-
-
- /**
- * 获取当前页面的第一个数据
- * @return
- */
- LocalDate getCurrPagerFirstDate();
-
- /**
- * 获取日历的类型
- * @return CalendarType.MONTH -> 月日历
- * CalendarType.WEEK -> 周日历
- */
- CalendarType getCalendarType();
-
-}
diff --git a/ncalendar/src/main/java/com/necer/view/WeekBar.java b/ncalendar/src/main/java/com/necer/view/WeekBar.java
deleted file mode 100644
index a9a6bc99..00000000
--- a/ncalendar/src/main/java/com/necer/view/WeekBar.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.necer.view;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatTextView;
-import android.text.TextPaint;
-import android.util.AttributeSet;
-
-import com.necer.R;
-import com.necer.utils.Attrs;
-
-/**
- * Created by necer on 2018/12/24.
- */
-public class WeekBar extends AppCompatTextView {
-
-
- public String[] days = {"日", "一", "二", "三", "四", "五", "六"};
-
- private int type;//一周的第一天是周几
- private TextPaint textPaint;
-
- public WeekBar(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
-
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NCalendar);
- type = ta.getInt(R.styleable.NCalendar_firstDayOfWeek, Attrs.SUNDAY);
- ta.recycle();
-
- textPaint = getPaint();
- textPaint.setTextAlign(Paint.Align.CENTER);
-
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- int paddingLeft = getPaddingLeft();
- int paddingRight = getPaddingRight();
-
- int paddingTop = getPaddingTop();
- int paddingBottom = getPaddingBottom();
-
- int width = getMeasuredWidth() - paddingRight - paddingLeft;
- int height = getMeasuredHeight() - paddingTop - paddingBottom;
- for (int i = 0; i < days.length; i++) {
- Rect rect = new Rect(paddingLeft + (i * width / days.length), paddingTop, paddingLeft + ((i + 1) * width / days.length), paddingTop + height);
- Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
- float top = fontMetrics.top;
- float bottom = fontMetrics.bottom;
- int baseLineY = (int) (rect.centerY() - top / 2 - bottom / 2);
- String day;
- if (type == Attrs.MONDAY) {
- int j = i + 1;
- day = days[j > days.length - 1 ? 0 : j];
- } else {
- day = days[i];
- }
- canvas.drawText(day, rect.centerX(), baseLineY, textPaint);
- }
- }
-
-}
diff --git a/ncalendar/src/main/res/values/attrs.xml b/ncalendar/src/main/res/values/attrs.xml
index 0b0810a9..116b623b 100644
--- a/ncalendar/src/main/res/values/attrs.xml
+++ b/ncalendar/src/main/res/values/attrs.xml
@@ -2,6 +2,7 @@
+
@@ -57,6 +58,7 @@
+
@@ -65,15 +67,18 @@
-
+
+
+
+
@@ -101,8 +106,11 @@
-
+
+
+
+
diff --git a/ncalendar/src/main/res/values/bools.xml b/ncalendar/src/main/res/values/bools.xml
index eb48c141..9fa83913 100644
--- a/ncalendar/src/main/res/values/bools.xml
+++ b/ncalendar/src/main/res/values/bools.xml
@@ -2,9 +2,12 @@
false
true
+ false
true
+ false
false
false
true
+ true
false
\ No newline at end of file
diff --git a/ncalendar/src/main/res/values/colors.xml b/ncalendar/src/main/res/values/colors.xml
index 5ff4e30b..09f54d53 100644
--- a/ncalendar/src/main/res/values/colors.xml
+++ b/ncalendar/src/main/res/values/colors.xml
@@ -7,11 +7,13 @@
#39AF81
#EC7230
#39AF81
- #ffffff
+ #FFFFFF
#444444
#39AF81
#666666
#B2B2B2
+ #B2B2B2
+ #00000000
\ No newline at end of file
diff --git a/ncalendar/src/main/res/values/dimens.xml b/ncalendar/src/main/res/values/dimens.xml
index 9c092f0b..2b423777 100644
--- a/ncalendar/src/main/res/values/dimens.xml
+++ b/ncalendar/src/main/res/values/dimens.xml
@@ -2,15 +2,17 @@
18sp
+ 14sp
10sp
15dp
10sp
15dp
- 18dp
+ 20dp
10sp
32dp
- 260sp
+ 240sp
300dp
+ 0dp
450dp
44dp
1dp
diff --git a/ncalendar/src/main/res/values/integers.xml b/ncalendar/src/main/res/values/integers.xml
index 32a979a3..a36c7fd8 100644
--- a/ncalendar/src/main/res/values/integers.xml
+++ b/ncalendar/src/main/res/values/integers.xml
@@ -1,7 +1,7 @@
- 240
+ 200
90
50
- 50
+ 50
\ No newline at end of file
diff --git a/ncalendar/src/main/res/values/strings.xml b/ncalendar/src/main/res/values/strings.xml
index af9196c5..be0f3aa4 100644
--- a/ncalendar/src/main/res/values/strings.xml
+++ b/ncalendar/src/main/res/values/strings.xml
@@ -4,6 +4,7 @@
休
班
日期超出许可范围
+ 设置了日历不可滑动,不能跳转到其他页面
startDate必须在endDate之前
startDate必须在1901-01-01之后
endDate必须在2099-12-31之前
@@ -13,7 +14,7 @@
设置的日期数量和MultipleCountModel冲突
jumpDate的参数需要正确的年月日数据
日历拉伸之后的高度必须大于正常高度,日历默认的正常高度为300dp
- NCalendar中的有且只能有一个直接子view
+ NCalendar中最多只能有一个直接子view
折叠日历不能使用此方法
折叠日历请调用setMonthCalendarBackground()和setWeekCalendarBackground()
不允许直接设置成CalendarState.MONTH_STRETCH,可以设置成CalendarState.WEEK或者CalendarState.MONTH