Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Sobot_module_Dev
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sobot_android
Sobot_module_Dev
Commits
335d6fe5
Commit
335d6fe5
authored
Oct 17, 2023
by
zhengnw@sobot.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widget 1.1.1 日历控件 可以选区间,也可以单选,自定义
parent
99e2ef44
Show whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
13151 additions
and
1 deletion
+13151
-1
sobot-widget-publish-mavencentral.gradle
sobot_widget/sobot-widget-publish-mavencentral.gradle
+1
-1
BaseMonthView.java
.../java/com/sobot/widget/ui/calenderview/BaseMonthView.java
+266
-0
BaseRecyclerAdapter.java
...com/sobot/widget/ui/calenderview/BaseRecyclerAdapter.java
+125
-0
BaseView.java
.../main/java/com/sobot/widget/ui/calenderview/BaseView.java
+430
-0
BaseWeekView.java
...n/java/com/sobot/widget/ui/calenderview/BaseWeekView.java
+294
-0
Calendar.java
.../main/java/com/sobot/widget/ui/calenderview/Calendar.java
+494
-0
CalendarLayout.java
...java/com/sobot/widget/ui/calenderview/CalendarLayout.java
+959
-0
CalendarUtil.java
...n/java/com/sobot/widget/ui/calenderview/CalendarUtil.java
+880
-0
CalendarView.java
...n/java/com/sobot/widget/ui/calenderview/CalendarView.java
+1930
-0
CalendarViewDelegate.java
...om/sobot/widget/ui/calenderview/CalendarViewDelegate.java
+1198
-0
CustomRangeMonthView.java
...om/sobot/widget/ui/calenderview/CustomRangeMonthView.java
+84
-0
CustomRangeWeekView.java
...com/sobot/widget/ui/calenderview/CustomRangeWeekView.java
+82
-0
CustomWeekBar.java
.../java/com/sobot/widget/ui/calenderview/CustomWeekBar.java
+62
-0
DefaultMonthView.java
...va/com/sobot/widget/ui/calenderview/DefaultMonthView.java
+116
-0
DefaultWeekView.java
...ava/com/sobot/widget/ui/calenderview/DefaultWeekView.java
+118
-0
DefaultYearView.java
...ava/com/sobot/widget/ui/calenderview/DefaultYearView.java
+94
-0
LunarCalendar.java
.../java/com/sobot/widget/ui/calenderview/LunarCalendar.java
+389
-0
LunarUtil.java
...main/java/com/sobot/widget/ui/calenderview/LunarUtil.java
+183
-0
Month.java
...src/main/java/com/sobot/widget/ui/calenderview/Month.java
+58
-0
MonthView.java
...main/java/com/sobot/widget/ui/calenderview/MonthView.java
+261
-0
MonthViewPager.java
...java/com/sobot/widget/ui/calenderview/MonthViewPager.java
+645
-0
MultiMonthView.java
...java/com/sobot/widget/ui/calenderview/MultiMonthView.java
+262
-0
MultiWeekView.java
.../java/com/sobot/widget/ui/calenderview/MultiWeekView.java
+215
-0
RangeMonthView.java
...java/com/sobot/widget/ui/calenderview/RangeMonthView.java
+295
-0
RangeWeekView.java
.../java/com/sobot/widget/ui/calenderview/RangeWeekView.java
+247
-0
SimpleMonthView.java
...ava/com/sobot/widget/ui/calenderview/SimpleMonthView.java
+68
-0
SimpleWeekView.java
...java/com/sobot/widget/ui/calenderview/SimpleWeekView.java
+62
-0
SolarTermUtil.java
.../java/com/sobot/widget/ui/calenderview/SolarTermUtil.java
+671
-0
TrunkBranchAnnals.java
...a/com/sobot/widget/ui/calenderview/TrunkBranchAnnals.java
+91
-0
WeekBar.java
...c/main/java/com/sobot/widget/ui/calenderview/WeekBar.java
+151
-0
WeekView.java
.../main/java/com/sobot/widget/ui/calenderview/WeekView.java
+196
-0
WeekViewPager.java
.../java/com/sobot/widget/ui/calenderview/WeekViewPager.java
+479
-0
YearRecyclerView.java
...va/com/sobot/widget/ui/calenderview/YearRecyclerView.java
+141
-0
YearView.java
.../main/java/com/sobot/widget/ui/calenderview/YearView.java
+546
-0
YearViewAdapter.java
...ava/com/sobot/widget/ui/calenderview/YearViewAdapter.java
+80
-0
YearViewPager.java
.../java/com/sobot/widget/ui/calenderview/YearViewPager.java
+204
-0
sobot_custom_week_bar.xml
sobot_widget/src/main/res/layout/sobot_custom_week_bar.xml
+77
-0
sobot_layout_calendar_view.xml
...widget/src/main/res/layout/sobot_layout_calendar_view.xml
+46
-0
sobot_week_bar.xml
sobot_widget/src/main/res/layout/sobot_week_bar.xml
+76
-0
strings_calender.xml
sobot_widget/src/main/res/values-en/strings_calender.xml
+216
-0
attrs.xml
sobot_widget/src/main/res/values/attrs.xml
+142
-0
strings_calender.xml
sobot_widget/src/main/res/values/strings_calender.xml
+217
-0
No files found.
sobot_widget/sobot-widget-publish-mavencentral.gradle
View file @
335d6fe5
...
...
@@ -13,7 +13,7 @@ ext {
PUBLISH_GROUP_ID
=
"com.sobot.library"
//项目包名
PUBLISH_ARTIFACT_ID
=
'widget'
//项目名
// PUBLISH_ARTIFACT_ID = 'widget_x' //项目名
PUBLISH_VERSION
=
'1.1.
0
'
//版本号
PUBLISH_VERSION
=
'1.1.
1
'
//版本号
}
...
...
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/BaseMonthView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
/**
* 月视图基础控件,可自由继承实现
* 可通过此扩展各种视图如:MonthView、RangeMonthView、MultiMonthView
*/
public
abstract
class
BaseMonthView
extends
BaseView
{
MonthViewPager
mMonthViewPager
;
/**
* 当前日历卡年份
*/
protected
int
mYear
;
/**
* 当前日历卡月份
*/
protected
int
mMonth
;
/**
* 日历的行数
*/
protected
int
mLineCount
;
/**
* 日历高度
*/
protected
int
mHeight
;
/**
* 下个月偏移的数量
*/
protected
int
mNextDiff
;
public
BaseMonthView
(
Context
context
)
{
super
(
context
);
}
/**
* 初始化日期
*
* @param year year
* @param month month
*/
final
void
initMonthWithDate
(
int
year
,
int
month
)
{
mYear
=
year
;
mMonth
=
month
;
initCalendar
();
mHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
,
mItemHeight
,
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
/**
* 初始化日历
*/
@SuppressLint
(
"WrongConstant"
)
private
void
initCalendar
()
{
mNextDiff
=
CalendarUtil
.
getMonthEndDiff
(
mYear
,
mMonth
,
mDelegate
.
getWeekStart
());
int
preDiff
=
CalendarUtil
.
getMonthViewStartDiff
(
mYear
,
mMonth
,
mDelegate
.
getWeekStart
());
int
monthDayCount
=
CalendarUtil
.
getMonthDaysCount
(
mYear
,
mMonth
);
mItems
=
CalendarUtil
.
initCalendarForMonthView
(
mYear
,
mMonth
,
mDelegate
.
getCurrentDay
(),
mDelegate
.
getWeekStart
());
if
(
mItems
.
contains
(
mDelegate
.
getCurrentDay
()))
{
mCurrentItem
=
mItems
.
indexOf
(
mDelegate
.
getCurrentDay
());
}
else
{
mCurrentItem
=
mItems
.
indexOf
(
mDelegate
.
mSelectedCalendar
);
}
if
(
mCurrentItem
>
0
&&
mDelegate
.
mCalendarInterceptListener
!=
null
&&
mDelegate
.
mCalendarInterceptListener
.
onCalendarIntercept
(
mDelegate
.
mSelectedCalendar
))
{
mCurrentItem
=
-
1
;
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
mLineCount
=
6
;
}
else
{
mLineCount
=
(
preDiff
+
monthDayCount
+
mNextDiff
)
/
7
;
}
addSchemesFromMap
();
invalidate
();
}
/**
* 获取点击选中的日期
*
* @return return
*/
protected
Calendar
getIndex
()
{
if
(
mItemWidth
==
0
||
mItemHeight
==
0
)
{
return
null
;
}
if
(
mX
<=
mDelegate
.
getCalendarPaddingLeft
()
||
mX
>=
getWidth
()
-
mDelegate
.
getCalendarPaddingRight
())
{
onClickCalendarPadding
();
return
null
;
}
int
indexX
=
(
int
)
(
mX
-
mDelegate
.
getCalendarPaddingLeft
())
/
mItemWidth
;
if
(
indexX
>=
7
)
{
indexX
=
6
;
}
int
indexY
=
(
int
)
mY
/
mItemHeight
;
int
position
=
indexY
*
7
+
indexX
;
// 选择项
if
(
position
>=
0
&&
position
<
mItems
.
size
())
{
return
mItems
.
get
(
position
);
}
return
null
;
}
private
void
onClickCalendarPadding
()
{
if
(
mDelegate
.
mClickCalendarPaddingListener
==
null
)
{
return
;
}
Calendar
calendar
=
null
;
int
indexX
=
(
int
)
(
mX
-
mDelegate
.
getCalendarPaddingLeft
())
/
mItemWidth
;
if
(
indexX
>=
7
)
{
indexX
=
6
;
}
int
indexY
=
(
int
)
mY
/
mItemHeight
;
int
position
=
indexY
*
7
+
indexX
;
// 选择项
if
(
position
>=
0
&&
position
<
mItems
.
size
())
{
calendar
=
mItems
.
get
(
position
);
}
if
(
calendar
==
null
)
{
return
;
}
mDelegate
.
mClickCalendarPaddingListener
.
onClickCalendarPadding
(
mX
,
mY
,
true
,
calendar
,
getClickCalendarPaddingObject
(
mX
,
mY
,
calendar
));
}
/**
* 获取点击事件处的对象
*
* @param x x
* @param y y
* @param adjacentCalendar adjacent calendar
* @return obj can as null
*/
@SuppressWarnings
(
"unused"
)
protected
Object
getClickCalendarPaddingObject
(
float
x
,
float
y
,
Calendar
adjacentCalendar
)
{
return
null
;
}
/**
* 记录已经选择的日期
*
* @param calendar calendar
*/
final
void
setSelectedCalendar
(
Calendar
calendar
)
{
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
}
/**
* 更新显示模式
*/
final
void
updateShowMode
()
{
mLineCount
=
CalendarUtil
.
getMonthViewLineCount
(
mYear
,
mMonth
,
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
mHeight
=
CalendarUtil
.
getMonthViewHeight
(
mYear
,
mMonth
,
mItemHeight
,
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
invalidate
();
}
/**
* 更新周起始
*/
final
void
updateWeekStart
()
{
initCalendar
();
mHeight
=
CalendarUtil
.
getMonthViewHeight
(
mYear
,
mMonth
,
mItemHeight
,
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
@Override
void
updateItemHeight
()
{
super
.
updateItemHeight
();
mHeight
=
CalendarUtil
.
getMonthViewHeight
(
mYear
,
mMonth
,
mItemHeight
,
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
@Override
void
updateCurrentDate
()
{
if
(
mItems
==
null
)
return
;
if
(
mItems
.
contains
(
mDelegate
.
getCurrentDay
()))
{
for
(
Calendar
a
:
mItems
)
{
//添加操作
a
.
setCurrentDay
(
false
);
}
int
index
=
mItems
.
indexOf
(
mDelegate
.
getCurrentDay
());
mItems
.
get
(
index
).
setCurrentDay
(
true
);
}
invalidate
();
}
/**
* 获取选中的下标
*
* @param calendar calendar
* @return 获取选中的下标
*/
protected
final
int
getSelectedIndex
(
Calendar
calendar
)
{
return
mItems
.
indexOf
(
calendar
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
if
(
mLineCount
!=
0
)
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
mHeight
,
MeasureSpec
.
EXACTLY
);
}
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
/**
* 开始绘制前的钩子,这里做一些初始化的操作,每次绘制只调用一次,性能高效
* 没有需要可忽略不实现
* 例如:
* 1、需要绘制圆形标记事件背景,可以在这里计算半径
* 2、绘制矩形选中效果,也可以在这里计算矩形宽和高
*/
protected
void
onPreviewHook
()
{
// TODO: 2017/11/16
}
/**
* 循环绘制开始的回调,不需要可忽略
* 绘制每个日历项的循环,用来计算baseLine、圆心坐标等都可以在这里实现
*
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
*/
protected
void
onLoopStart
(
int
x
,
int
y
)
{
// TODO: 2017/11/16
}
@Override
protected
void
onDestroy
()
{
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/BaseRecyclerAdapter.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 基本的适配器
*/
abstract
class
BaseRecyclerAdapter
<
T
>
extends
RecyclerView
.
Adapter
{
@SuppressWarnings
(
"all"
)
LayoutInflater
mInflater
;
private
List
<
T
>
mItems
;
private
OnItemClickListener
onItemClickListener
;
private
OnClickListener
onClickListener
;
Context
mContext
;
BaseRecyclerAdapter
(
Context
context
)
{
mContext
=
context
;
this
.
mItems
=
new
ArrayList
<>();
mInflater
=
LayoutInflater
.
from
(
context
);
onClickListener
=
new
OnClickListener
()
{
@Override
public
void
onClick
(
int
position
,
long
itemId
)
{
if
(
onItemClickListener
!=
null
)
onItemClickListener
.
onItemClick
(
position
,
itemId
);
}
};
}
@SuppressWarnings
(
"ConstantConditions"
)
@NonNull
@Override
public
RecyclerView
.
ViewHolder
onCreateViewHolder
(
@NonNull
ViewGroup
parent
,
int
viewType
)
{
final
RecyclerView
.
ViewHolder
holder
=
onCreateDefaultViewHolder
(
parent
,
viewType
);
if
(
holder
!=
null
)
{
holder
.
itemView
.
setTag
(
holder
);
holder
.
itemView
.
setOnClickListener
(
onClickListener
);
}
return
holder
;
}
@Override
public
void
onBindViewHolder
(
@NonNull
RecyclerView
.
ViewHolder
holder
,
int
position
)
{
onBindViewHolder
(
holder
,
mItems
.
get
(
position
),
position
);
}
abstract
RecyclerView
.
ViewHolder
onCreateDefaultViewHolder
(
ViewGroup
parent
,
int
type
);
abstract
void
onBindViewHolder
(
RecyclerView
.
ViewHolder
holder
,
T
item
,
int
position
);
@Override
public
int
getItemCount
()
{
return
mItems
.
size
();
}
void
setOnItemClickListener
(
OnItemClickListener
onItemClickListener
)
{
this
.
onItemClickListener
=
onItemClickListener
;
}
@SuppressWarnings
(
"unused"
)
void
addAll
(
List
<
T
>
items
)
{
if
(
items
!=
null
&&
items
.
size
()
>
0
)
{
mItems
.
addAll
(
items
);
notifyItemRangeInserted
(
mItems
.
size
(),
items
.
size
());
}
}
final
void
addItem
(
T
item
)
{
if
(
item
!=
null
)
{
this
.
mItems
.
add
(
item
);
notifyItemChanged
(
mItems
.
size
());
}
}
@SuppressWarnings
(
"unused"
)
final
List
<
T
>
getItems
()
{
return
mItems
;
}
final
T
getItem
(
int
position
)
{
if
(
position
<
0
||
position
>=
mItems
.
size
())
return
null
;
return
mItems
.
get
(
position
);
}
static
abstract
class
OnClickListener
implements
View
.
OnClickListener
{
@Override
public
void
onClick
(
View
v
)
{
RecyclerView
.
ViewHolder
holder
=
(
RecyclerView
.
ViewHolder
)
v
.
getTag
();
onClick
(
holder
.
getAdapterPosition
(),
holder
.
getItemId
());
}
public
abstract
void
onClick
(
int
position
,
long
itemId
);
}
interface
OnItemClickListener
{
void
onItemClick
(
int
position
,
long
itemId
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/BaseView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.support.annotation.Nullable
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
java.util.List
;
/**
* 基本的日历View,派生出MonthView 和 WeekView
*/
public
abstract
class
BaseView
extends
View
implements
View
.
OnClickListener
,
View
.
OnLongClickListener
{
CalendarViewDelegate
mDelegate
;
/**
* 当前月份日期的笔
*/
protected
Paint
mCurMonthTextPaint
=
new
Paint
();
/**
* 其它月份日期颜色
*/
protected
Paint
mOtherMonthTextPaint
=
new
Paint
();
/**
* 当前月份农历文本颜色
*/
protected
Paint
mCurMonthLunarTextPaint
=
new
Paint
();
/**
* 当前月份农历文本颜色
*/
protected
Paint
mSelectedLunarTextPaint
=
new
Paint
();
/**
* 其它月份农历文本颜色
*/
protected
Paint
mOtherMonthLunarTextPaint
=
new
Paint
();
/**
* 其它月份农历文本颜色
*/
protected
Paint
mSchemeLunarTextPaint
=
new
Paint
();
/**
* 标记的日期背景颜色画笔
*/
protected
Paint
mSchemePaint
=
new
Paint
();
/**
* 被选择的日期背景色
*/
protected
Paint
mSelectedPaint
=
new
Paint
();
/**
* 标记的文本画笔
*/
protected
Paint
mSchemeTextPaint
=
new
Paint
();
/**
* 选中的文本画笔
*/
protected
Paint
mSelectTextPaint
=
new
Paint
();
/**
* 当前日期文本颜色画笔
*/
protected
Paint
mCurDayTextPaint
=
new
Paint
();
/**
* 当前日期文本颜色画笔
*/
protected
Paint
mCurDayLunarTextPaint
=
new
Paint
();
/**
* 日历布局,需要在日历下方放自己的布局
*/
CalendarLayout
mParentLayout
;
/**
* 日历项
*/
protected
List
<
Calendar
>
mItems
;
/**
* 每一项的高度
*/
protected
int
mItemHeight
;
/**
* 每一项的宽度
*/
protected
int
mItemWidth
;
/**
* Text的基线
*/
protected
float
mTextBaseLine
;
/**
* 点击的x、y坐标
*/
protected
float
mX
,
mY
;
/**
* 是否点击
*/
boolean
isClick
=
true
;
/**
* 字体大小
*/
static
final
int
TEXT_SIZE
=
14
;
/**
* 当前点击项
*/
int
mCurrentItem
=
-
1
;
/**
* 周起始
*/
int
mWeekStartWidth
;
public
BaseView
(
Context
context
)
{
this
(
context
,
null
);
}
public
BaseView
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initPaint
(
context
);
}
/**
* 初始化配置
*
* @param context context
*/
private
void
initPaint
(
Context
context
)
{
mCurMonthTextPaint
.
setAntiAlias
(
true
);
mCurMonthTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurMonthTextPaint
.
setColor
(
0xFF111111
);
mCurMonthTextPaint
.
setFakeBoldText
(
true
);
mCurMonthTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mOtherMonthTextPaint
.
setAntiAlias
(
true
);
mOtherMonthTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mOtherMonthTextPaint
.
setColor
(
0xFFe1e1e1
);
mOtherMonthTextPaint
.
setFakeBoldText
(
true
);
mOtherMonthTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mCurMonthLunarTextPaint
.
setAntiAlias
(
true
);
mCurMonthLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSelectedLunarTextPaint
.
setAntiAlias
(
true
);
mSelectedLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mOtherMonthLunarTextPaint
.
setAntiAlias
(
true
);
mOtherMonthLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeLunarTextPaint
.
setAntiAlias
(
true
);
mSchemeLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeTextPaint
.
setAntiAlias
(
true
);
mSchemeTextPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemeTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeTextPaint
.
setColor
(
0xffed5353
);
mSchemeTextPaint
.
setFakeBoldText
(
true
);
mSchemeTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mSelectTextPaint
.
setAntiAlias
(
true
);
mSelectTextPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSelectTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSelectTextPaint
.
setColor
(
0xffed5353
);
mSelectTextPaint
.
setFakeBoldText
(
true
);
mSelectTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mSchemePaint
.
setAntiAlias
(
true
);
mSchemePaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemePaint
.
setStrokeWidth
(
2
);
mSchemePaint
.
setColor
(
0xffefefef
);
mCurDayTextPaint
.
setAntiAlias
(
true
);
mCurDayTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurDayTextPaint
.
setColor
(
Color
.
RED
);
mCurDayTextPaint
.
setFakeBoldText
(
true
);
mCurDayTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mCurDayLunarTextPaint
.
setAntiAlias
(
true
);
mCurDayLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurDayLunarTextPaint
.
setColor
(
Color
.
RED
);
mCurDayLunarTextPaint
.
setFakeBoldText
(
true
);
mCurDayLunarTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
TEXT_SIZE
));
mSelectedPaint
.
setAntiAlias
(
true
);
mSelectedPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSelectedPaint
.
setStrokeWidth
(
2
);
setOnClickListener
(
this
);
setOnLongClickListener
(
this
);
}
/**
* 初始化所有UI配置
*
* @param delegate delegate
*/
final
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
mWeekStartWidth
=
mDelegate
.
getWeekStart
();
updateStyle
();
updateItemHeight
();
initPaint
();
}
final
void
updateStyle
()
{
if
(
mDelegate
==
null
)
{
return
;
}
this
.
mCurDayTextPaint
.
setColor
(
mDelegate
.
getCurDayTextColor
());
this
.
mCurDayLunarTextPaint
.
setColor
(
mDelegate
.
getCurDayLunarTextColor
());
this
.
mCurMonthTextPaint
.
setColor
(
mDelegate
.
getCurrentMonthTextColor
());
this
.
mOtherMonthTextPaint
.
setColor
(
mDelegate
.
getOtherMonthTextColor
());
this
.
mCurMonthLunarTextPaint
.
setColor
(
mDelegate
.
getCurrentMonthLunarTextColor
());
this
.
mSelectedLunarTextPaint
.
setColor
(
mDelegate
.
getSelectedLunarTextColor
());
this
.
mSelectTextPaint
.
setColor
(
mDelegate
.
getSelectedTextColor
());
this
.
mOtherMonthLunarTextPaint
.
setColor
(
mDelegate
.
getOtherMonthLunarTextColor
());
this
.
mSchemeLunarTextPaint
.
setColor
(
mDelegate
.
getSchemeLunarTextColor
());
this
.
mSchemePaint
.
setColor
(
mDelegate
.
getSchemeThemeColor
());
this
.
mSchemeTextPaint
.
setColor
(
mDelegate
.
getSchemeTextColor
());
this
.
mCurMonthTextPaint
.
setTextSize
(
mDelegate
.
getDayTextSize
());
this
.
mOtherMonthTextPaint
.
setTextSize
(
mDelegate
.
getDayTextSize
());
this
.
mCurDayTextPaint
.
setTextSize
(
mDelegate
.
getDayTextSize
());
this
.
mSchemeTextPaint
.
setTextSize
(
mDelegate
.
getDayTextSize
());
this
.
mSelectTextPaint
.
setTextSize
(
mDelegate
.
getDayTextSize
());
this
.
mCurMonthLunarTextPaint
.
setTextSize
(
mDelegate
.
getLunarTextSize
());
this
.
mSelectedLunarTextPaint
.
setTextSize
(
mDelegate
.
getLunarTextSize
());
this
.
mCurDayLunarTextPaint
.
setTextSize
(
mDelegate
.
getLunarTextSize
());
this
.
mOtherMonthLunarTextPaint
.
setTextSize
(
mDelegate
.
getLunarTextSize
());
this
.
mSchemeLunarTextPaint
.
setTextSize
(
mDelegate
.
getLunarTextSize
());
this
.
mSelectedPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
this
.
mSelectedPaint
.
setColor
(
mDelegate
.
getSelectedThemeColor
());
}
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
void
updateItemHeight
()
{
this
.
mItemHeight
=
mDelegate
.
getCalendarItemHeight
();
Paint
.
FontMetrics
metrics
=
mCurMonthTextPaint
.
getFontMetrics
();
mTextBaseLine
=
mItemHeight
/
2
-
metrics
.
descent
+
(
metrics
.
bottom
-
metrics
.
top
)
/
2
;
}
/**
* 移除事件
*/
final
void
removeSchemes
()
{
for
(
Calendar
a
:
mItems
)
{
a
.
setScheme
(
""
);
a
.
setSchemeColor
(
0
);
a
.
setSchemes
(
null
);
}
}
/**
* 添加事件标记,来自Map
*/
final
void
addSchemesFromMap
()
{
if
(
mDelegate
.
mSchemeDatesMap
==
null
||
mDelegate
.
mSchemeDatesMap
.
size
()
==
0
)
{
return
;
}
for
(
Calendar
a
:
mItems
)
{
if
(
mDelegate
.
mSchemeDatesMap
.
containsKey
(
a
.
toString
()))
{
Calendar
d
=
mDelegate
.
mSchemeDatesMap
.
get
(
a
.
toString
());
if
(
d
==
null
)
{
continue
;
}
a
.
setScheme
(
TextUtils
.
isEmpty
(
d
.
getScheme
())
?
mDelegate
.
getSchemeText
()
:
d
.
getScheme
());
a
.
setSchemeColor
(
d
.
getSchemeColor
());
a
.
setSchemes
(
d
.
getSchemes
());
}
else
{
a
.
setScheme
(
""
);
a
.
setSchemeColor
(
0
);
a
.
setSchemes
(
null
);
}
}
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(
event
.
getPointerCount
()
>
1
)
return
false
;
switch
(
event
.
getAction
())
{
case
MotionEvent
.
ACTION_DOWN
:
mX
=
event
.
getX
();
mY
=
event
.
getY
();
isClick
=
true
;
break
;
case
MotionEvent
.
ACTION_MOVE
:
float
mDY
;
if
(
isClick
)
{
mDY
=
event
.
getY
()
-
mY
;
isClick
=
Math
.
abs
(
mDY
)
<=
50
;
}
break
;
case
MotionEvent
.
ACTION_UP
:
mX
=
event
.
getX
();
mY
=
event
.
getY
();
break
;
}
return
super
.
onTouchEvent
(
event
);
}
/**
* 开始绘制前的钩子,这里做一些初始化的操作,每次绘制只调用一次,性能高效
* 没有需要可忽略不实现
* 例如:
* 1、需要绘制圆形标记事件背景,可以在这里计算半径
* 2、绘制矩形选中效果,也可以在这里计算矩形宽和高
*/
protected
void
onPreviewHook
()
{
// TODO: 2017/11/16
}
/**
* 是否是选中的
*
* @param calendar calendar
* @return true or false
*/
protected
boolean
isSelected
(
Calendar
calendar
)
{
return
mItems
!=
null
&&
mItems
.
indexOf
(
calendar
)
==
mCurrentItem
;
}
/**
* 更新事件
*/
final
void
update
()
{
if
(
mDelegate
.
mSchemeDatesMap
==
null
||
mDelegate
.
mSchemeDatesMap
.
size
()
==
0
)
{
//清空操作
removeSchemes
();
invalidate
();
return
;
}
addSchemesFromMap
();
invalidate
();
}
/**
* 是否拦截日期,此设置续设置mCalendarInterceptListener
*
* @param calendar calendar
* @return 是否拦截日期
*/
protected
final
boolean
onCalendarIntercept
(
Calendar
calendar
)
{
return
mDelegate
.
mCalendarInterceptListener
!=
null
&&
mDelegate
.
mCalendarInterceptListener
.
onCalendarIntercept
(
calendar
);
}
/**
* 是否在日期范围内
*
* @param calendar calendar
* @return 是否在日期范围内
*/
protected
final
boolean
isInRange
(
Calendar
calendar
)
{
return
mDelegate
!=
null
&&
CalendarUtil
.
isCalendarInRange
(
calendar
,
mDelegate
);
}
/**
* 跟新当前日期
*/
abstract
void
updateCurrentDate
();
/**
* 销毁
*/
protected
abstract
void
onDestroy
();
protected
int
getWeekStartWith
()
{
return
mDelegate
!=
null
?
mDelegate
.
getWeekStart
()
:
CalendarViewDelegate
.
WEEK_START_WITH_SUN
;
}
protected
int
getCalendarPaddingLeft
()
{
return
mDelegate
!=
null
?
mDelegate
.
getCalendarPaddingLeft
()
:
0
;
}
protected
int
getCalendarPaddingRight
()
{
return
mDelegate
!=
null
?
mDelegate
.
getCalendarPaddingRight
()
:
0
;
}
/**
* 初始化画笔相关
*/
protected
void
initPaint
()
{
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/BaseWeekView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
/**
* 最基础周视图,因为日历UI采用热插拔实现,所以这里必须继承实现,达到UI一致即可
* 可通过此扩展各种视图如:WeekView、RangeWeekView
*/
public
abstract
class
BaseWeekView
extends
BaseView
{
public
BaseWeekView
(
Context
context
)
{
super
(
context
);
}
/**
* 初始化周视图控件
*
* @param calendar calendar
*/
final
void
setup
(
Calendar
calendar
)
{
mItems
=
CalendarUtil
.
initCalendarForWeekView
(
calendar
,
mDelegate
,
mDelegate
.
getWeekStart
());
addSchemesFromMap
();
invalidate
();
}
/**
* 记录已经选择的日期
*
* @param calendar calendar
*/
final
void
setSelectedCalendar
(
Calendar
calendar
)
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_SINGLE
&&
!
calendar
.
equals
(
mDelegate
.
mSelectedCalendar
))
{
return
;
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
}
/**
* 周视图切换点击默认位置
*
* @param calendar calendar
* @param isNotice isNotice
*/
final
void
performClickCalendar
(
Calendar
calendar
,
boolean
isNotice
)
{
if
(
mParentLayout
==
null
||
mDelegate
.
mInnerListener
==
null
||
mItems
==
null
||
mItems
.
size
()
==
0
)
{
return
;
}
int
week
=
CalendarUtil
.
getWeekViewIndexFromCalendar
(
calendar
,
mDelegate
.
getWeekStart
());
if
(
mItems
.
contains
(
mDelegate
.
getCurrentDay
()))
{
week
=
CalendarUtil
.
getWeekViewIndexFromCalendar
(
mDelegate
.
getCurrentDay
(),
mDelegate
.
getWeekStart
());
}
int
curIndex
=
week
;
Calendar
currentCalendar
=
mItems
.
get
(
week
);
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
if
(
mItems
.
contains
(
mDelegate
.
mSelectedCalendar
))
{
currentCalendar
=
mDelegate
.
mSelectedCalendar
;
}
else
{
mCurrentItem
=
-
1
;
}
}
if
(!
isInRange
(
currentCalendar
))
{
curIndex
=
getEdgeIndex
(
isMinRangeEdge
(
currentCalendar
));
currentCalendar
=
mItems
.
get
(
curIndex
);
}
currentCalendar
.
setCurrentDay
(
currentCalendar
.
equals
(
mDelegate
.
getCurrentDay
()));
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
currentCalendar
,
false
);
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
currentCalendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
isNotice
&&
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
currentCalendar
,
false
);
}
mParentLayout
.
updateContentViewTranslateY
();
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
mCurrentItem
=
curIndex
;
}
if
(!
mDelegate
.
isShowYearSelectedLayout
&&
mDelegate
.
mIndexCalendar
!=
null
&&
calendar
.
getYear
()
!=
mDelegate
.
mIndexCalendar
.
getYear
()
&&
mDelegate
.
mYearChangeListener
!=
null
)
{
mDelegate
.
mYearChangeListener
.
onYearChange
(
mDelegate
.
mIndexCalendar
.
getYear
());
}
mDelegate
.
mIndexCalendar
=
currentCalendar
;
invalidate
();
}
/**
* 是否是最小访问边界了
*
* @param calendar calendar
* @return 是否是最小访问边界了
*/
final
boolean
isMinRangeEdge
(
Calendar
calendar
)
{
java
.
util
.
Calendar
c
=
java
.
util
.
Calendar
.
getInstance
();
c
.
set
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
()
-
1
,
mDelegate
.
getMinYearDay
());
long
minTime
=
c
.
getTimeInMillis
();
c
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
());
long
curTime
=
c
.
getTimeInMillis
();
return
curTime
<
minTime
;
}
/**
* 获得边界范围内下标
*
* @param isMinEdge isMinEdge
* @return 获得边界范围内下标
*/
final
int
getEdgeIndex
(
boolean
isMinEdge
)
{
for
(
int
i
=
0
;
i
<
mItems
.
size
();
i
++)
{
Calendar
item
=
mItems
.
get
(
i
);
boolean
isInRange
=
isInRange
(
item
);
if
(
isMinEdge
&&
isInRange
)
{
return
i
;
}
else
if
(!
isMinEdge
&&
!
isInRange
)
{
return
i
-
1
;
}
}
return
isMinEdge
?
6
:
0
;
}
/**
* 获取点击的日历
*
* @return 获取点击的日历
*/
protected
Calendar
getIndex
()
{
if
(
mX
<=
mDelegate
.
getCalendarPaddingLeft
()
||
mX
>=
getWidth
()
-
mDelegate
.
getCalendarPaddingRight
())
{
onClickCalendarPadding
();
return
null
;
}
int
indexX
=
(
int
)
(
mX
-
mDelegate
.
getCalendarPaddingLeft
())
/
mItemWidth
;
if
(
indexX
>=
7
)
{
indexX
=
6
;
}
int
indexY
=
(
int
)
mY
/
mItemHeight
;
int
position
=
indexY
*
7
+
indexX
;
// 选择项
if
(
position
>=
0
&&
position
<
mItems
.
size
())
return
mItems
.
get
(
position
);
return
null
;
}
private
void
onClickCalendarPadding
()
{
if
(
mDelegate
.
mClickCalendarPaddingListener
==
null
)
{
return
;
}
Calendar
calendar
=
null
;
int
indexX
=
(
int
)
(
mX
-
mDelegate
.
getCalendarPaddingLeft
())
/
mItemWidth
;
if
(
indexX
>=
7
)
{
indexX
=
6
;
}
int
indexY
=
(
int
)
mY
/
mItemHeight
;
int
position
=
indexY
*
7
+
indexX
;
// 选择项
if
(
position
>=
0
&&
position
<
mItems
.
size
())
{
calendar
=
mItems
.
get
(
position
);
}
if
(
calendar
==
null
)
{
return
;
}
mDelegate
.
mClickCalendarPaddingListener
.
onClickCalendarPadding
(
mX
,
mY
,
false
,
calendar
,
getClickCalendarPaddingObject
(
mX
,
mY
,
calendar
));
}
/**
* /**
* 获取点击事件处的对象
*
* @param x x
* @param y y
* @param adjacentCalendar adjacent calendar
* @return obj can as null
*/
@SuppressWarnings
(
"unused"
)
protected
Object
getClickCalendarPaddingObject
(
float
x
,
float
y
,
Calendar
adjacentCalendar
)
{
return
null
;
}
/**
* 更新显示模式
*/
final
void
updateShowMode
()
{
invalidate
();
}
/**
* 更新周起始
*/
final
void
updateWeekStart
()
{
int
position
=
(
int
)
getTag
();
Calendar
calendar
=
CalendarUtil
.
getFirstCalendarStartWithMinCalendar
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
position
+
1
,
mDelegate
.
getWeekStart
());
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
setup
(
calendar
);
}
/**
* 更新当选模式
*/
final
void
updateSingleSelect
()
{
if
(!
mItems
.
contains
(
mDelegate
.
mSelectedCalendar
))
{
mCurrentItem
=
-
1
;
invalidate
();
}
}
@Override
void
updateCurrentDate
()
{
if
(
mItems
==
null
)
return
;
if
(
mItems
.
contains
(
mDelegate
.
getCurrentDay
()))
{
for
(
Calendar
a
:
mItems
)
{
//添加操作
a
.
setCurrentDay
(
false
);
}
int
index
=
mItems
.
indexOf
(
mDelegate
.
getCurrentDay
());
mItems
.
get
(
index
).
setCurrentDay
(
true
);
}
invalidate
();
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
mItemHeight
,
MeasureSpec
.
EXACTLY
);
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
/**
* 开始绘制前的钩子,这里做一些初始化的操作,每次绘制只调用一次,性能高效
* 没有需要可忽略不实现
* 例如:
* 1、需要绘制圆形标记事件背景,可以在这里计算半径
* 2、绘制矩形选中效果,也可以在这里计算矩形宽和高
*/
protected
void
onPreviewHook
()
{
// TODO: 2017/11/16
}
/**
* 循环绘制开始的回调,不需要可忽略
* 绘制每个日历项的循环,用来计算baseLine、圆心坐标等都可以在这里实现
*
* @param x 日历Card x起点坐标
*/
@SuppressWarnings
(
"unused"
)
protected
void
onLoopStart
(
int
x
)
{
// TODO: 2017/11/16
}
@Override
protected
void
onDestroy
()
{
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/Calendar.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.text.TextUtils
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.TimeZone
;
/**
* 日历对象、
*/
@SuppressWarnings
(
"all"
)
public
final
class
Calendar
implements
Serializable
,
Comparable
<
Calendar
>
{
private
static
final
long
serialVersionUID
=
141315161718191143L
;
/**
* 时区
*/
private
String
zone
;
/**
* 年
*/
private
int
year
;
/**
* 月1-12
*/
private
int
month
;
/**
* 如果是闰月,则返回闰月
*/
private
int
leapMonth
;
/**
* 日1-31
*/
private
int
day
;
/**
* 是否是闰年
*/
private
boolean
isLeapYear
;
/**
* 是否是本月,这里对应的是月视图的本月,而非当前月份,请注意
*/
private
boolean
isCurrentMonth
;
/**
* 是否是今天
*/
private
boolean
isCurrentDay
;
/**
* 农历字符串,没有特别大的意义,用来做简单的农历或者节日标记
* 建议通过lunarCakendar获取完整的农历日期
*/
private
String
lunar
;
/**
* 24节气
*/
private
String
solarTerm
;
/**
* 公历节日
*/
private
String
gregorianFestival
;
/**
* 传统农历节日
*/
private
String
traditionFestival
;
/**
* 计划,可以用来标记当天是否有任务,这里是默认的,如果使用多标记,请使用下面API
* using addScheme(int schemeColor,String scheme); multi scheme
*/
private
String
scheme
;
/**
* 各种自定义标记颜色、没有则选择默认颜色,如果使用多标记,请使用下面API
* using addScheme(int schemeColor,String scheme); multi scheme
*/
private
int
schemeColor
;
/**
* 多标记
* multi scheme,using addScheme();
*/
private
List
<
Scheme
>
schemes
;
/**
* 是否是周末
*/
private
boolean
isWeekend
;
/**
* 星期,0-6 对应周日到周一
*/
private
int
week
;
/**
* 获取完整的农历日期
*/
private
Calendar
lunarCalendar
;
public
void
setZone
(
String
zone
){
this
.
zone
=
zone
;
}
public
int
getYear
()
{
return
year
;
}
public
void
setYear
(
int
year
)
{
this
.
year
=
year
;
}
public
int
getMonth
()
{
return
month
;
}
public
void
setMonth
(
int
month
)
{
this
.
month
=
month
;
}
public
int
getDay
()
{
return
day
;
}
public
void
setDay
(
int
day
)
{
this
.
day
=
day
;
}
public
boolean
isCurrentMonth
()
{
return
isCurrentMonth
;
}
public
void
setCurrentMonth
(
boolean
currentMonth
)
{
this
.
isCurrentMonth
=
currentMonth
;
}
public
boolean
isCurrentDay
()
{
return
isCurrentDay
;
}
public
void
setCurrentDay
(
boolean
currentDay
)
{
isCurrentDay
=
currentDay
;
}
public
String
getLunar
()
{
return
lunar
;
}
public
void
setLunar
(
String
lunar
)
{
this
.
lunar
=
lunar
;
}
public
String
getScheme
()
{
return
scheme
;
}
public
void
setScheme
(
String
scheme
)
{
this
.
scheme
=
scheme
;
}
public
int
getSchemeColor
()
{
return
schemeColor
;
}
public
void
setSchemeColor
(
int
schemeColor
)
{
this
.
schemeColor
=
schemeColor
;
}
public
List
<
Scheme
>
getSchemes
()
{
return
schemes
;
}
public
void
setSchemes
(
List
<
Scheme
>
schemes
)
{
this
.
schemes
=
schemes
;
}
public
void
addScheme
(
Scheme
scheme
)
{
if
(
schemes
==
null
)
{
schemes
=
new
ArrayList
<>();
}
schemes
.
add
(
scheme
);
}
public
void
addScheme
(
int
schemeColor
,
String
scheme
)
{
if
(
schemes
==
null
)
{
schemes
=
new
ArrayList
<>();
}
schemes
.
add
(
new
Scheme
(
schemeColor
,
scheme
));
}
public
void
addScheme
(
int
type
,
int
schemeColor
,
String
scheme
)
{
if
(
schemes
==
null
)
{
schemes
=
new
ArrayList
<>();
}
schemes
.
add
(
new
Scheme
(
type
,
schemeColor
,
scheme
));
}
public
void
addScheme
(
int
type
,
int
schemeColor
,
String
scheme
,
String
other
)
{
if
(
schemes
==
null
)
{
schemes
=
new
ArrayList
<>();
}
schemes
.
add
(
new
Scheme
(
type
,
schemeColor
,
scheme
,
other
));
}
public
void
addScheme
(
int
schemeColor
,
String
scheme
,
String
other
)
{
if
(
schemes
==
null
)
{
schemes
=
new
ArrayList
<>();
}
schemes
.
add
(
new
Scheme
(
schemeColor
,
scheme
,
other
));
}
public
boolean
isWeekend
()
{
return
isWeekend
;
}
public
void
setWeekend
(
boolean
weekend
)
{
isWeekend
=
weekend
;
}
public
int
getWeek
()
{
return
week
;
}
public
void
setWeek
(
int
week
)
{
this
.
week
=
week
;
}
public
Calendar
getLunarCalendar
()
{
return
lunarCalendar
;
}
public
void
setLunarCalendar
(
Calendar
lunarCakendar
)
{
this
.
lunarCalendar
=
lunarCakendar
;
}
public
String
getSolarTerm
()
{
return
solarTerm
;
}
public
void
setSolarTerm
(
String
solarTerm
)
{
this
.
solarTerm
=
solarTerm
;
}
public
String
getGregorianFestival
()
{
return
gregorianFestival
;
}
public
void
setGregorianFestival
(
String
gregorianFestival
)
{
this
.
gregorianFestival
=
gregorianFestival
;
}
public
int
getLeapMonth
()
{
return
leapMonth
;
}
public
void
setLeapMonth
(
int
leapMonth
)
{
this
.
leapMonth
=
leapMonth
;
}
public
boolean
isLeapYear
()
{
return
isLeapYear
;
}
public
void
setLeapYear
(
boolean
leapYear
)
{
isLeapYear
=
leapYear
;
}
public
String
getTraditionFestival
()
{
return
traditionFestival
;
}
public
void
setTraditionFestival
(
String
traditionFestival
)
{
this
.
traditionFestival
=
traditionFestival
;
}
public
boolean
hasScheme
()
{
if
(
schemes
!=
null
&&
schemes
.
size
()
!=
0
)
{
return
true
;
}
if
(!
TextUtils
.
isEmpty
(
scheme
))
{
return
true
;
}
return
false
;
}
/**
* 是否是相同月份
*
* @param calendar 日期
* @return 是否是相同月份
*/
public
boolean
isSameMonth
(
Calendar
calendar
)
{
return
year
==
calendar
.
getYear
()
&&
month
==
calendar
.
getMonth
();
}
/**
* 比较日期
*
* @param calendar 日期
* @return <0 0 >0
*/
public
int
compareTo
(
Calendar
calendar
)
{
if
(
calendar
==
null
)
{
return
1
;
}
return
toString
().
compareTo
(
calendar
.
toString
());
}
/**
* 运算差距多少天
*
* @param calendar calendar
* @return 运算差距多少天
*/
public
final
int
differ
(
Calendar
calendar
)
{
return
CalendarUtil
.
differ
(
this
,
calendar
);
}
/**
* 日期是否可用
*
* @return 日期是否可用
*/
public
boolean
isAvailable
()
{
return
year
>
0
&
month
>
0
&
day
>
0
&
day
<=
31
&
month
<=
12
&
year
>=
1900
&
year
<=
2099
;
}
/**
* 获取当前日历对应时间戳
*
* @return getTimeInMillis
*/
public
long
getTimeInMillis
()
{
java
.
util
.
Calendar
calendar
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
)){
calendar
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
calendar
.
set
(
java
.
util
.
Calendar
.
YEAR
,
year
);
calendar
.
set
(
java
.
util
.
Calendar
.
MONTH
,
month
-
1
);
calendar
.
set
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
,
day
);
return
calendar
.
getTimeInMillis
();
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
o
!=
null
&&
o
instanceof
Calendar
)
{
if
(((
Calendar
)
o
).
getYear
()
==
year
&&
((
Calendar
)
o
).
getMonth
()
==
month
&&
((
Calendar
)
o
).
getDay
()
==
day
)
return
true
;
}
return
super
.
equals
(
o
);
}
@Override
public
String
toString
()
{
return
year
+
""
+
(
month
<
10
?
"0"
+
month
:
month
)
+
""
+
(
day
<
10
?
"0"
+
day
:
day
);
}
// @Override
// public int compare(Calendar lhs, Calendar rhs) {
// if (lhs == null || rhs == null) {
// return 0;
// }
// int result = lhs.compareTo(rhs);
// return result;
// }
final
void
mergeScheme
(
Calendar
calendar
,
String
defaultScheme
)
{
if
(
calendar
==
null
)
return
;
setScheme
(
TextUtils
.
isEmpty
(
calendar
.
getScheme
())
?
defaultScheme
:
calendar
.
getScheme
());
setSchemeColor
(
calendar
.
getSchemeColor
());
setSchemes
(
calendar
.
getSchemes
());
}
final
void
clearScheme
()
{
setScheme
(
""
);
setSchemeColor
(
0
);
setSchemes
(
null
);
}
/**
* 事件标记服务,现在多类型的事务标记建议使用这个
*/
public
final
static
class
Scheme
implements
Serializable
{
private
int
type
;
private
int
shcemeColor
;
private
String
scheme
;
private
String
other
;
private
Object
obj
;
public
Scheme
()
{
}
public
Scheme
(
int
type
,
int
shcemeColor
,
String
scheme
,
String
other
)
{
this
.
type
=
type
;
this
.
shcemeColor
=
shcemeColor
;
this
.
scheme
=
scheme
;
this
.
other
=
other
;
}
public
Scheme
(
int
type
,
int
shcemeColor
,
String
scheme
)
{
this
.
type
=
type
;
this
.
shcemeColor
=
shcemeColor
;
this
.
scheme
=
scheme
;
}
public
Scheme
(
int
shcemeColor
,
String
scheme
)
{
this
.
shcemeColor
=
shcemeColor
;
this
.
scheme
=
scheme
;
}
public
Scheme
(
int
shcemeColor
,
String
scheme
,
String
other
)
{
this
.
shcemeColor
=
shcemeColor
;
this
.
scheme
=
scheme
;
this
.
other
=
other
;
}
public
int
getShcemeColor
()
{
return
shcemeColor
;
}
public
void
setShcemeColor
(
int
shcemeColor
)
{
this
.
shcemeColor
=
shcemeColor
;
}
public
String
getScheme
()
{
return
scheme
;
}
public
void
setScheme
(
String
scheme
)
{
this
.
scheme
=
scheme
;
}
public
String
getOther
()
{
return
other
;
}
public
void
setOther
(
String
other
)
{
this
.
other
=
other
;
}
public
int
getType
()
{
return
type
;
}
public
void
setType
(
int
type
)
{
this
.
type
=
type
;
}
public
Object
getObj
()
{
return
obj
;
}
public
void
setObj
(
Object
obj
)
{
this
.
obj
=
obj
;
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CalendarLayout.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.animation.Animator
;
import
android.animation.AnimatorListenerAdapter
;
import
android.animation.ObjectAnimator
;
import
android.animation.ValueAnimator
;
import
android.animation.ValueAnimator.AnimatorUpdateListener
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.os.Bundle
;
import
android.os.Parcelable
;
import
android.support.annotation.Nullable
;
import
android.support.v7.widget.RecyclerView
;
import
android.util.AttributeSet
;
import
android.view.MotionEvent
;
import
android.view.VelocityTracker
;
import
android.view.View
;
import
android.view.ViewConfiguration
;
import
android.view.ViewGroup
;
import
android.view.animation.LinearInterpolator
;
import
android.widget.AbsListView
;
import
android.widget.LinearLayout
;
import
com.sobot.widget.R
;
/**
* 日历布局
*/
@SuppressWarnings
(
"unused"
)
public
class
CalendarLayout
extends
LinearLayout
{
/**
* 多点触控支持
*/
private
int
mActivePointerId
;
private
static
final
int
ACTIVE_POINTER
=
1
;
private
static
final
int
INVALID_POINTER
=
-
1
;
/**
* 周月视图
*/
private
static
final
int
CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW
=
0
;
/**
* 仅周视图
*/
private
static
final
int
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
=
1
;
/**
* 仅月视图
*/
private
static
final
int
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
=
2
;
/**
* 默认展开
*/
private
static
final
int
STATUS_EXPAND
=
0
;
/**
* 默认收缩
*/
private
static
final
int
STATUS_SHRINK
=
1
;
/**
* 默认状态
*/
private
int
mDefaultStatus
;
private
boolean
isWeekView
;
/**
* 星期栏
*/
WeekBar
mWeekBar
;
/**
* 自定义ViewPager,月视图
*/
MonthViewPager
mMonthView
;
/**
* 日历
*/
CalendarView
mCalendarView
;
/**
* 自定义的周视图
*/
WeekViewPager
mWeekPager
;
/**
* 年视图
*/
YearViewPager
mYearView
;
/**
* ContentView
*/
ViewGroup
mContentView
;
/**
* 默认手势
*/
private
static
final
int
GESTURE_MODE_DEFAULT
=
0
;
// /**
// * 仅日历有效
// */
// private static final int GESTURE_MODE_ONLY_CALENDAR = 1;
/**
* 禁用手势
*/
private
static
final
int
GESTURE_MODE_DISABLED
=
2
;
/**
* 手势模式
*/
private
int
mGestureMode
;
private
int
mCalendarShowMode
;
private
int
mContentViewTranslateY
;
//ContentView 可滑动的最大距离距离 , 固定
private
int
mViewPagerTranslateY
=
0
;
// ViewPager可以平移的距离,不代表mMonthView的平移距离
private
float
downY
;
private
float
mLastY
;
private
float
mLastX
;
private
boolean
isAnimating
=
false
;
/**
* 内容布局id
*/
private
int
mContentViewId
;
/**
* 手速判断
*/
private
VelocityTracker
mVelocityTracker
;
private
int
mMaximumVelocity
;
private
int
mItemHeight
;
private
CalendarViewDelegate
mDelegate
;
public
CalendarLayout
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
setOrientation
(
LinearLayout
.
VERTICAL
);
TypedArray
array
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
Sobot_CalendarLayout
);
mContentViewId
=
array
.
getResourceId
(
R
.
styleable
.
Sobot_CalendarLayout_calendar_content_view_id
,
0
);
mDefaultStatus
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarLayout_default_status
,
STATUS_EXPAND
);
mCalendarShowMode
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarLayout_calendar_show_mode
,
CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW
);
mGestureMode
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarLayout_gesture_mode
,
GESTURE_MODE_DEFAULT
);
array
.
recycle
();
mVelocityTracker
=
VelocityTracker
.
obtain
();
final
ViewConfiguration
configuration
=
ViewConfiguration
.
get
(
context
);
int
mTouchSlop
=
configuration
.
getScaledTouchSlop
();
mMaximumVelocity
=
configuration
.
getScaledMaximumFlingVelocity
();
}
/**
* 初始化
*
* @param delegate delegate
*/
final
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
mItemHeight
=
mDelegate
.
getCalendarItemHeight
();
initCalendarPosition
(
delegate
.
mSelectedCalendar
.
isAvailable
()
?
delegate
.
mSelectedCalendar
:
delegate
.
createCurrentDate
());
updateContentViewTranslateY
();
}
/**
* 初始化当前时间的位置
*
* @param cur 当前日期时间
*/
private
void
initCalendarPosition
(
Calendar
cur
)
{
int
diff
=
CalendarUtil
.
getMonthViewStartDiff
(
cur
,
mDelegate
.
getWeekStart
());
int
size
=
diff
+
cur
.
getDay
()
-
1
;
updateSelectPosition
(
size
);
}
/**
* 当前第几项被选中,更新平移量
*
* @param selectPosition 月视图被点击的position
*/
final
void
updateSelectPosition
(
int
selectPosition
)
{
int
line
=
(
selectPosition
+
7
)
/
7
;
mViewPagerTranslateY
=
(
line
-
1
)
*
mItemHeight
;
}
/**
* 设置选中的周,更新位置
*
* @param week week
*/
final
void
updateSelectWeek
(
int
week
)
{
mViewPagerTranslateY
=
(
week
-
1
)
*
mItemHeight
;
}
/**
* 更新内容ContentView可平移的最大距离
*/
void
updateContentViewTranslateY
()
{
Calendar
calendar
=
mDelegate
.
mIndexCalendar
;
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
mContentViewTranslateY
=
5
*
mItemHeight
;
}
else
{
mContentViewTranslateY
=
CalendarUtil
.
getMonthViewHeight
(
calendar
.
getYear
(),
calendar
.
getMonth
(),
mItemHeight
,
mDelegate
.
getWeekStart
())
-
mItemHeight
;
}
//已经显示周视图,则需要动态平移contentView的高度
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
if
(
mContentView
==
null
)
return
;
mContentView
.
setTranslationY
(-
mContentViewTranslateY
);
}
}
/**
* 更新日历项高度
*/
final
void
updateCalendarItemHeight
()
{
mItemHeight
=
mDelegate
.
getCalendarItemHeight
();
if
(
mContentView
==
null
)
return
;
Calendar
calendar
=
mDelegate
.
mIndexCalendar
;
updateSelectWeek
(
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
()));
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
mContentViewTranslateY
=
5
*
mItemHeight
;
}
else
{
mContentViewTranslateY
=
CalendarUtil
.
getMonthViewHeight
(
calendar
.
getYear
(),
calendar
.
getMonth
(),
mItemHeight
,
mDelegate
.
getWeekStart
())
-
mItemHeight
;
}
translationViewPager
();
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
mContentView
.
setTranslationY
(-
mContentViewTranslateY
);
}
}
/**
* 隐藏日历
*/
public
void
hideCalendarView
()
{
if
(
mCalendarView
==
null
)
{
return
;
}
mCalendarView
.
setVisibility
(
GONE
);
if
(!
isExpand
())
{
expand
(
0
);
}
requestLayout
();
}
/**
* 显示日历
*/
public
void
showCalendarView
()
{
mCalendarView
.
setVisibility
(
VISIBLE
);
requestLayout
();
}
@SuppressLint
(
"ClickableViewAccessibility"
)
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
)
{
//禁用手势,或者只显示某种视图
return
false
;
}
if
(
mDelegate
==
null
)
{
return
false
;
}
if
(
mDelegate
.
isShowYearSelectedLayout
)
{
return
false
;
}
if
(
mContentView
==
null
||
mCalendarView
==
null
||
mCalendarView
.
getVisibility
()
==
GONE
)
{
return
false
;
}
int
action
=
event
.
getAction
();
float
y
=
event
.
getY
();
mVelocityTracker
.
addMovement
(
event
);
switch
(
action
)
{
case
MotionEvent
.
ACTION_DOWN
:
int
index
=
event
.
getActionIndex
();
mActivePointerId
=
event
.
getPointerId
(
index
);
mLastY
=
downY
=
y
;
return
true
;
case
MotionEvent
.
ACTION_POINTER_DOWN
:
{
final
int
indexx
=
event
.
getActionIndex
();
mActivePointerId
=
event
.
getPointerId
(
indexx
);
if
(
mActivePointerId
==
0
)
{
//核心代码:就是让下面的 dy = y- mLastY == 0,避免抖动
mLastY
=
event
.
getY
(
mActivePointerId
);
}
break
;
}
case
MotionEvent
.
ACTION_MOVE
:
getPointerIndex
(
event
,
mActivePointerId
);
if
(
mActivePointerId
==
INVALID_POINTER
)
{
//如果切换了手指,那把mLastY换到最新手指的y坐标即可,核心就是让下面的 dy== 0,避免抖动
mLastY
=
y
;
mActivePointerId
=
ACTIVE_POINTER
;
}
float
dy
=
y
-
mLastY
;
//向上滑动,并且contentView平移到最大距离,显示周视图
if
(
dy
<
0
&&
mContentView
.
getTranslationY
()
==
-
mContentViewTranslateY
)
{
mLastY
=
y
;
event
.
setAction
(
MotionEvent
.
ACTION_DOWN
);
dispatchTouchEvent
(
event
);
mWeekPager
.
setVisibility
(
VISIBLE
);
mMonthView
.
setVisibility
(
INVISIBLE
);
if
(!
isWeekView
&&
mDelegate
.
mViewChangeListener
!=
null
)
{
mDelegate
.
mViewChangeListener
.
onViewChange
(
false
);
}
isWeekView
=
true
;
return
true
;
}
hideWeek
(
false
);
//向下滑动,并且contentView已经完全平移到底部
if
(
dy
>
0
&&
mContentView
.
getTranslationY
()
+
dy
>=
0
)
{
mContentView
.
setTranslationY
(
0
);
translationViewPager
();
mLastY
=
y
;
return
super
.
onTouchEvent
(
event
);
}
//向上滑动,并且contentView已经平移到最大距离,则contentView平移到最大的距离
if
(
dy
<
0
&&
mContentView
.
getTranslationY
()
+
dy
<=
-
mContentViewTranslateY
)
{
mContentView
.
setTranslationY
(-
mContentViewTranslateY
);
translationViewPager
();
mLastY
=
y
;
return
super
.
onTouchEvent
(
event
);
}
//否则按比例平移
mContentView
.
setTranslationY
(
mContentView
.
getTranslationY
()
+
dy
);
translationViewPager
();
mLastY
=
y
;
break
;
case
MotionEvent
.
ACTION_CANCEL
:
case
MotionEvent
.
ACTION_POINTER_UP
:
int
pointerIndex
=
getPointerIndex
(
event
,
mActivePointerId
);
if
(
mActivePointerId
==
INVALID_POINTER
)
break
;
mLastY
=
event
.
getY
(
pointerIndex
);
break
;
case
MotionEvent
.
ACTION_UP
:
final
VelocityTracker
velocityTracker
=
mVelocityTracker
;
velocityTracker
.
computeCurrentVelocity
(
1000
,
mMaximumVelocity
);
float
mYVelocity
=
velocityTracker
.
getYVelocity
();
if
(
mContentView
.
getTranslationY
()
==
0
||
mContentView
.
getTranslationY
()
==
mContentViewTranslateY
)
{
expand
();
break
;
}
if
(
Math
.
abs
(
mYVelocity
)
>=
800
)
{
if
(
mYVelocity
<
0
)
{
shrink
();
}
else
{
expand
();
}
return
super
.
onTouchEvent
(
event
);
}
if
(
event
.
getY
()
-
downY
>
0
)
{
expand
();
}
else
{
shrink
();
}
break
;
}
return
super
.
onTouchEvent
(
event
);
}
@Override
public
boolean
dispatchTouchEvent
(
MotionEvent
ev
)
{
if
(
isAnimating
)
{
return
super
.
dispatchTouchEvent
(
ev
);
}
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
)
{
return
super
.
dispatchTouchEvent
(
ev
);
}
if
(
mYearView
==
null
||
mCalendarView
==
null
||
mCalendarView
.
getVisibility
()
==
GONE
||
mContentView
==
null
||
mContentView
.
getVisibility
()
!=
VISIBLE
)
{
return
super
.
dispatchTouchEvent
(
ev
);
}
if
(
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
)
{
return
super
.
dispatchTouchEvent
(
ev
);
}
if
(
mYearView
.
getVisibility
()
==
VISIBLE
||
mDelegate
.
isShowYearSelectedLayout
)
{
return
super
.
dispatchTouchEvent
(
ev
);
}
final
int
action
=
ev
.
getAction
();
float
y
=
ev
.
getY
();
if
(
action
==
MotionEvent
.
ACTION_MOVE
)
{
float
dy
=
y
-
mLastY
;
/*
* 如果向下滚动,有 2 种情况处理 且y在ViewPager下方
* 1、RecyclerView 或者其它滚动的View,当mContentView滚动到顶部时,拦截事件
* 2、非滚动控件,直接拦截事件
*/
if
(
dy
>
0
&&
mContentView
.
getTranslationY
()
==
-
mContentViewTranslateY
)
{
if
(
isScrollTop
())
{
requestDisallowInterceptTouchEvent
(
false
);
//父View向子View拦截分发事件
return
super
.
dispatchTouchEvent
(
ev
);
}
}
}
return
super
.
dispatchTouchEvent
(
ev
);
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
ev
)
{
if
(
isAnimating
)
{
return
true
;
}
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
)
{
return
false
;
}
if
(
mYearView
==
null
||
mCalendarView
==
null
||
mCalendarView
.
getVisibility
()
==
GONE
||
mContentView
==
null
||
mContentView
.
getVisibility
()
!=
VISIBLE
)
{
return
super
.
onInterceptTouchEvent
(
ev
);
}
if
(
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
)
{
return
false
;
}
if
(
mYearView
.
getVisibility
()
==
VISIBLE
||
mDelegate
.
isShowYearSelectedLayout
)
{
return
super
.
onInterceptTouchEvent
(
ev
);
}
final
int
action
=
ev
.
getAction
();
float
y
=
ev
.
getY
();
float
x
=
ev
.
getX
();
switch
(
action
)
{
case
MotionEvent
.
ACTION_DOWN
:
int
index
=
ev
.
getActionIndex
();
mActivePointerId
=
ev
.
getPointerId
(
index
);
mLastY
=
downY
=
y
;
mLastX
=
x
;
break
;
case
MotionEvent
.
ACTION_MOVE
:
float
dy
=
y
-
mLastY
;
float
dx
=
x
-
mLastX
;
/*
如果向上滚动,且ViewPager已经收缩,不拦截事件
*/
if
(
dy
<
0
&&
mContentView
.
getTranslationY
()
==
-
mContentViewTranslateY
)
{
return
false
;
}
/*
* 如果向下滚动,有 2 种情况处理 且y在ViewPager下方
* 1、RecyclerView 或者其它滚动的View,当mContentView滚动到顶部时,拦截事件
* 2、非滚动控件,直接拦截事件
*/
if
(
dy
>
0
&&
mContentView
.
getTranslationY
()
==
-
mContentViewTranslateY
&&
y
>=
mDelegate
.
getCalendarItemHeight
()
+
mDelegate
.
getWeekBarHeight
())
{
if
(!
isScrollTop
())
{
return
false
;
}
}
if
(
dy
>
0
&&
mContentView
.
getTranslationY
()
==
0
&&
y
>=
CalendarUtil
.
dipToPx
(
getContext
(),
98
))
{
return
false
;
}
if
(
Math
.
abs
(
dy
)
>
Math
.
abs
(
dx
)
)
{
//纵向滑动距离大于横向滑动距离,拦截滑动事件
if
((
dy
>
0
&&
mContentView
.
getTranslationY
()
<=
0
)
||
(
dy
<
0
&&
mContentView
.
getTranslationY
()
>=
-
mContentViewTranslateY
))
{
mLastY
=
y
;
return
true
;
}
}
break
;
}
return
super
.
onInterceptTouchEvent
(
ev
);
}
private
int
getPointerIndex
(
MotionEvent
ev
,
int
id
)
{
int
activePointerIndex
=
ev
.
findPointerIndex
(
id
);
if
(
activePointerIndex
==
-
1
)
{
mActivePointerId
=
INVALID_POINTER
;
}
return
activePointerIndex
;
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
if
(
mContentView
==
null
||
mCalendarView
==
null
)
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
return
;
}
int
year
=
mDelegate
.
mIndexCalendar
.
getYear
();
int
month
=
mDelegate
.
mIndexCalendar
.
getMonth
();
int
weekBarHeight
=
CalendarUtil
.
dipToPx
(
getContext
(),
1
)
+
mDelegate
.
getWeekBarHeight
();
int
monthHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
())
+
weekBarHeight
;
int
height
=
MeasureSpec
.
getSize
(
heightMeasureSpec
);
if
(
mDelegate
.
isFullScreenCalendar
())
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
int
heightSpec
=
MeasureSpec
.
makeMeasureSpec
(
height
-
weekBarHeight
-
mDelegate
.
getCalendarItemHeight
(),
MeasureSpec
.
EXACTLY
);
mContentView
.
measure
(
widthMeasureSpec
,
heightSpec
);
mContentView
.
layout
(
mContentView
.
getLeft
(),
mContentView
.
getTop
(),
mContentView
.
getRight
(),
mContentView
.
getBottom
());
return
;
}
if
(
monthHeight
>=
height
&&
mMonthView
.
getHeight
()
>
0
)
{
height
=
monthHeight
;
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
monthHeight
+
weekBarHeight
+
mDelegate
.
getWeekBarHeight
(),
MeasureSpec
.
EXACTLY
);
}
else
if
(
monthHeight
<
height
&&
mMonthView
.
getHeight
()
>
0
)
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
height
,
MeasureSpec
.
EXACTLY
);
}
int
h
;
if
(
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
||
mCalendarView
.
getVisibility
()
==
GONE
)
{
h
=
height
-
(
mCalendarView
.
getVisibility
()
==
GONE
?
0
:
mCalendarView
.
getHeight
());
}
else
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
&&
!
isAnimating
)
{
if
(
isExpand
())
{
h
=
height
-
monthHeight
;
}
else
{
h
=
height
-
weekBarHeight
-
mItemHeight
;
}
}
else
{
h
=
height
-
weekBarHeight
-
mItemHeight
;
}
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
int
heightSpec
=
MeasureSpec
.
makeMeasureSpec
(
h
,
MeasureSpec
.
EXACTLY
);
mContentView
.
measure
(
widthMeasureSpec
,
heightSpec
);
mContentView
.
layout
(
mContentView
.
getLeft
(),
mContentView
.
getTop
(),
mContentView
.
getRight
(),
mContentView
.
getBottom
());
}
@Override
protected
void
onFinishInflate
()
{
super
.
onFinishInflate
();
mMonthView
=
findViewById
(
R
.
id
.
vp_month
);
mWeekPager
=
findViewById
(
R
.
id
.
vp_week
);
if
(
getChildCount
()
>
0
)
{
mCalendarView
=
(
CalendarView
)
getChildAt
(
0
);
}
mContentView
=
findViewById
(
mContentViewId
);
mYearView
=
findViewById
(
R
.
id
.
selectLayout
);
}
/**
* 平移ViewPager月视图
*/
private
void
translationViewPager
()
{
float
percent
=
mContentView
.
getTranslationY
()
*
1.0f
/
mContentViewTranslateY
;
mMonthView
.
setTranslationY
(
mViewPagerTranslateY
*
percent
);
}
public
void
setModeBothMonthWeekView
()
{
mCalendarShowMode
=
CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW
;
requestLayout
();
}
public
void
setModeOnlyWeekView
()
{
mCalendarShowMode
=
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
;
requestLayout
();
}
public
void
setModeOnlyMonthView
()
{
mCalendarShowMode
=
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
;
requestLayout
();
}
@Nullable
@Override
protected
Parcelable
onSaveInstanceState
()
{
Bundle
bundle
=
new
Bundle
();
Parcelable
parcelable
=
super
.
onSaveInstanceState
();
bundle
.
putParcelable
(
"super"
,
parcelable
);
bundle
.
putBoolean
(
"isExpand"
,
isExpand
());
return
bundle
;
}
@Override
protected
void
onRestoreInstanceState
(
Parcelable
state
)
{
Bundle
bundle
=
(
Bundle
)
state
;
Parcelable
superData
=
bundle
.
getParcelable
(
"super"
);
boolean
isExpand
=
bundle
.
getBoolean
(
"isExpand"
);
if
(
isExpand
)
{
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
expand
(
0
);
}
});
}
else
{
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
shrink
(
0
);
}
});
}
super
.
onRestoreInstanceState
(
superData
);
}
/**
* 是否展开了
*
* @return isExpand
*/
public
final
boolean
isExpand
()
{
return
mMonthView
.
getVisibility
()
==
VISIBLE
;
}
public
boolean
expand
()
{
return
expand
(
240
);
}
/**
* 展开
*
* @param duration 时长
* @return 展开是否成功
*/
public
boolean
expand
(
int
duration
)
{
if
(
isAnimating
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
||
mContentView
==
null
)
return
false
;
if
(
mMonthView
.
getVisibility
()
!=
VISIBLE
)
{
mWeekPager
.
setVisibility
(
GONE
);
onShowMonthView
();
isWeekView
=
false
;
mMonthView
.
setVisibility
(
VISIBLE
);
}
ObjectAnimator
objectAnimator
=
ObjectAnimator
.
ofFloat
(
mContentView
,
"translationY"
,
mContentView
.
getTranslationY
(),
0
f
);
objectAnimator
.
setDuration
(
duration
);
objectAnimator
.
addUpdateListener
(
new
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
float
currentValue
=
(
Float
)
animation
.
getAnimatedValue
();
float
percent
=
currentValue
*
1.0f
/
mContentViewTranslateY
;
mMonthView
.
setTranslationY
(
mViewPagerTranslateY
*
percent
);
isAnimating
=
true
;
}
});
objectAnimator
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
isAnimating
=
false
;
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
)
{
requestLayout
();
}
hideWeek
(
true
);
if
(
mDelegate
.
mViewChangeListener
!=
null
&&
isWeekView
)
{
mDelegate
.
mViewChangeListener
.
onViewChange
(
true
);
}
isWeekView
=
false
;
}
});
objectAnimator
.
start
();
return
true
;
}
public
boolean
shrink
()
{
return
shrink
(
240
);
}
/**
* 收缩
*
* @param duration 时长
* @return 成功或者失败
*/
public
boolean
shrink
(
int
duration
)
{
if
(
mGestureMode
==
GESTURE_MODE_DISABLED
)
{
requestLayout
();
}
if
(
isAnimating
||
mContentView
==
null
)
{
return
false
;
}
ObjectAnimator
objectAnimator
=
ObjectAnimator
.
ofFloat
(
mContentView
,
"translationY"
,
mContentView
.
getTranslationY
(),
-
mContentViewTranslateY
);
objectAnimator
.
setDuration
(
duration
);
objectAnimator
.
addUpdateListener
(
new
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
float
currentValue
=
(
Float
)
animation
.
getAnimatedValue
();
float
percent
=
currentValue
*
1.0f
/
mContentViewTranslateY
;
mMonthView
.
setTranslationY
(
mViewPagerTranslateY
*
percent
);
isAnimating
=
true
;
}
});
objectAnimator
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
isAnimating
=
false
;
showWeek
();
isWeekView
=
true
;
}
});
objectAnimator
.
start
();
return
true
;
}
/**
* 初始化状态
*/
final
void
initStatus
()
{
if
((
mDefaultStatus
==
STATUS_SHRINK
||
mCalendarShowMode
==
CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW
)
&&
mCalendarShowMode
!=
CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW
)
{
if
(
mContentView
==
null
)
{
mWeekPager
.
setVisibility
(
VISIBLE
);
mMonthView
.
setVisibility
(
GONE
);
return
;
}
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
ObjectAnimator
objectAnimator
=
ObjectAnimator
.
ofFloat
(
mContentView
,
"translationY"
,
mContentView
.
getTranslationY
(),
-
mContentViewTranslateY
);
objectAnimator
.
setDuration
(
0
);
objectAnimator
.
addUpdateListener
(
new
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
float
currentValue
=
(
Float
)
animation
.
getAnimatedValue
();
float
percent
=
currentValue
*
1.0f
/
mContentViewTranslateY
;
mMonthView
.
setTranslationY
(
mViewPagerTranslateY
*
percent
);
isAnimating
=
true
;
}
});
objectAnimator
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
isAnimating
=
false
;
isWeekView
=
true
;
showWeek
();
if
(
mDelegate
==
null
||
mDelegate
.
mViewChangeListener
==
null
)
{
return
;
}
mDelegate
.
mViewChangeListener
.
onViewChange
(
false
);
}
});
objectAnimator
.
start
();
}
});
}
else
{
if
(
mDelegate
.
mViewChangeListener
==
null
)
{
return
;
}
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
mDelegate
.
mViewChangeListener
.
onViewChange
(
true
);
}
});
}
}
/**
* 隐藏周视图
*/
private
void
hideWeek
(
boolean
isNotify
)
{
if
(
isNotify
)
{
onShowMonthView
();
}
mWeekPager
.
setVisibility
(
GONE
);
mMonthView
.
setVisibility
(
VISIBLE
);
}
/**
* 显示周视图
*/
private
void
showWeek
()
{
onShowWeekView
();
if
(
mWeekPager
!=
null
&&
mWeekPager
.
getAdapter
()
!=
null
)
{
mWeekPager
.
getAdapter
().
notifyDataSetChanged
();
mWeekPager
.
setVisibility
(
VISIBLE
);
}
mMonthView
.
setVisibility
(
INVISIBLE
);
}
/**
* 周视图显示事件
*/
private
void
onShowWeekView
()
{
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
return
;
}
if
(
mDelegate
!=
null
&&
mDelegate
.
mViewChangeListener
!=
null
&&
!
isWeekView
)
{
mDelegate
.
mViewChangeListener
.
onViewChange
(
false
);
}
}
/**
* 周视图显示事件
*/
private
void
onShowMonthView
()
{
if
(
mMonthView
.
getVisibility
()
==
VISIBLE
)
{
return
;
}
if
(
mDelegate
!=
null
&&
mDelegate
.
mViewChangeListener
!=
null
&&
isWeekView
)
{
mDelegate
.
mViewChangeListener
.
onViewChange
(
true
);
}
}
/**
* ContentView是否滚动到顶部 如果完全不适合,就复写这个方法
*
* @return 是否滚动到顶部
*/
protected
boolean
isScrollTop
()
{
if
(
mContentView
instanceof
CalendarScrollView
)
{
return
((
CalendarScrollView
)
mContentView
).
isScrollToTop
();
}
if
(
mContentView
instanceof
RecyclerView
)
return
((
RecyclerView
)
mContentView
).
computeVerticalScrollOffset
()
==
0
;
if
(
mContentView
instanceof
AbsListView
)
{
boolean
result
=
false
;
AbsListView
listView
=
(
AbsListView
)
mContentView
;
if
(
listView
.
getFirstVisiblePosition
()
==
0
)
{
final
View
topChildView
=
listView
.
getChildAt
(
0
);
result
=
topChildView
.
getTop
()
==
0
;
}
return
result
;
}
return
mContentView
.
getScrollY
()
==
0
;
}
/**
* 隐藏内容布局
*/
@SuppressLint
(
"NewApi"
)
final
void
hideContentView
()
{
if
(
mContentView
==
null
)
return
;
mContentView
.
animate
()
.
translationY
(
getHeight
()
-
mMonthView
.
getHeight
())
.
setDuration
(
220
)
.
setInterpolator
(
new
LinearInterpolator
())
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
mContentView
.
setVisibility
(
INVISIBLE
);
mContentView
.
clearAnimation
();
}
});
}
/**
* 显示内容布局
*/
@SuppressLint
(
"NewApi"
)
final
void
showContentView
()
{
if
(
mContentView
==
null
)
return
;
mContentView
.
setTranslationY
(
getHeight
()
-
mMonthView
.
getHeight
());
mContentView
.
setVisibility
(
VISIBLE
);
mContentView
.
animate
()
.
translationY
(
0
)
.
setDuration
(
180
)
.
setInterpolator
(
new
LinearInterpolator
())
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
}
});
}
@SuppressWarnings
(
"unused"
)
private
int
getCalendarViewHeight
()
{
return
mMonthView
.
getVisibility
()
==
VISIBLE
?
mDelegate
.
getWeekBarHeight
()
+
mMonthView
.
getHeight
()
:
mDelegate
.
getWeekBarHeight
()
+
mDelegate
.
getCalendarItemHeight
();
}
/**
* 如果有十分特别的ContentView,可以自定义实现这个接口
*/
public
interface
CalendarScrollView
{
/**
* 是否滚动到顶部
*
* @return 是否滚动到顶部
*/
boolean
isScrollToTop
();
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CalendarUtil.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.text.TextUtils
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.TimeZone
;
/**
* 一些日期辅助计算工具
*/
@SuppressWarnings
(
"all"
)
public
final
class
CalendarUtil
{
public
static
String
zone
;
private
static
final
long
ONE_DAY
=
1000
*
3600
*
24
;
@SuppressLint
(
"SimpleDateFormat"
)
static
int
getDate
(
String
formatStr
,
Date
date
)
{
SimpleDateFormat
format
=
new
SimpleDateFormat
(
formatStr
);
if
(!
TextUtils
.
isEmpty
(
zone
))
{
format
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
return
Integer
.
parseInt
(
format
.
format
(
date
));
}
/**
* 判断一个日期是否是周末,即周六日
*
* @param calendar calendar
* @return 判断一个日期是否是周末,即周六日
*/
public
static
boolean
isWeekend
(
Calendar
calendar
)
{
int
week
=
getWeekFormCalendar
(
calendar
);
return
week
==
0
||
week
==
6
;
}
/**
* 获取某月的天数
*
* @param year 年
* @param month 月
* @return 某月的天数
*/
public
static
int
getMonthDaysCount
(
int
year
,
int
month
)
{
int
count
=
0
;
//判断大月份
if
(
month
==
1
||
month
==
3
||
month
==
5
||
month
==
7
||
month
==
8
||
month
==
10
||
month
==
12
)
{
count
=
31
;
}
//判断小月
if
(
month
==
4
||
month
==
6
||
month
==
9
||
month
==
11
)
{
count
=
30
;
}
//判断平年与闰年
if
(
month
==
2
)
{
if
(
isLeapYear
(
year
))
{
count
=
29
;
}
else
{
count
=
28
;
}
}
return
count
;
}
/**
* 是否是闰年
*
* @param year year
* @return 是否是闰年
*/
public
static
boolean
isLeapYear
(
int
year
)
{
return
((
year
%
4
==
0
)
&&
(
year
%
100
!=
0
))
||
(
year
%
400
==
0
);
}
public
static
int
getMonthViewLineCount
(
int
year
,
int
month
,
int
weekStartWith
,
int
mode
)
{
if
(
mode
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
return
6
;
}
int
nextDiff
=
CalendarUtil
.
getMonthEndDiff
(
year
,
month
,
weekStartWith
);
int
preDiff
=
CalendarUtil
.
getMonthViewStartDiff
(
year
,
month
,
weekStartWith
);
int
monthDayCount
=
CalendarUtil
.
getMonthDaysCount
(
year
,
month
);
return
(
preDiff
+
monthDayCount
+
nextDiff
)
/
7
;
}
/**
* 获取月视图的确切高度
* Test pass
*
* @param year 年
* @param month 月
* @param itemHeight 每项的高度
* @param weekStartWith 周起始
* @return 不需要多余行的高度
*/
public
static
int
getMonthViewHeight
(
int
year
,
int
month
,
int
itemHeight
,
int
weekStartWith
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
date
.
set
(
year
,
month
-
1
,
1
,
12
,
0
,
0
);
int
preDiff
=
getMonthViewStartDiff
(
year
,
month
,
weekStartWith
);
int
monthDaysCount
=
getMonthDaysCount
(
year
,
month
);
int
nextDiff
=
getMonthEndDiff
(
year
,
month
,
monthDaysCount
,
weekStartWith
);
return
(
preDiff
+
monthDaysCount
+
nextDiff
)
/
7
*
itemHeight
;
}
/**
* 获取月视图的确切高度
* Test pass
*
* @param year 年
* @param month 月
* @param itemHeight 每项的高度
* @param weekStartWith weekStartWith
* @param mode mode
* @return 不需要多余行的高度
*/
public
static
int
getMonthViewHeight
(
int
year
,
int
month
,
int
itemHeight
,
int
weekStartWith
,
int
mode
)
{
if
(
mode
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
return
itemHeight
*
6
;
}
return
getMonthViewHeight
(
year
,
month
,
itemHeight
,
weekStartWith
);
}
/**
* 获取某天在该月的第几周,换言之就是获取这一天在该月视图的第几行,第几周,根据周起始动态获取
* Test pass,单元测试通过
*
* @param calendar calendar
* @param weekStart 其实星期是哪一天?
* @return 获取某天在该月的第几周 the week line in MonthView
*/
public
static
int
getWeekFromDayInMonth
(
Calendar
calendar
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
1
,
12
,
0
,
0
);
//该月第一天为星期几,星期天 == 0
int
diff
=
getMonthViewStartDiff
(
calendar
,
weekStart
);
return
(
calendar
.
getDay
()
+
diff
-
1
)
/
7
+
1
;
}
/**
* 获取上一个日子
*
* @param calendar calendar
* @return 获取上一个日子
*/
public
static
Calendar
getPreCalendar
(
Calendar
calendar
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
(),
12
,
0
,
0
);
//
long
timeMills
=
date
.
getTimeInMillis
();
//获得起始时间戳
date
.
setTimeInMillis
(
timeMills
-
ONE_DAY
);
Calendar
preCalendar
=
new
Calendar
();
preCalendar
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
preCalendar
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
preCalendar
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
return
preCalendar
;
}
public
static
Calendar
getNextCalendar
(
Calendar
calendar
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
(),
12
,
0
,
0
);
//
long
timeMills
=
date
.
getTimeInMillis
();
//获得起始时间戳
date
.
setTimeInMillis
(
timeMills
+
ONE_DAY
);
Calendar
nextCalendar
=
new
Calendar
();
nextCalendar
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
nextCalendar
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
nextCalendar
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
return
nextCalendar
;
}
/**
* DAY_OF_WEEK return 1 2 3 4 5 6 7,偏移了一位
* 获取日期所在月视图对应的起始偏移量
* Test pass
*
* @param calendar calendar
* @param weekStart weekStart 星期的起始
* @return 获取日期所在月视图对应的起始偏移量 the start diff with MonthView
*/
static
int
getMonthViewStartDiff
(
Calendar
calendar
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
1
,
12
,
0
,
0
);
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
)
{
return
week
-
1
;
}
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_MON
)
{
return
week
==
1
?
6
:
week
-
weekStart
;
}
return
week
==
CalendarViewDelegate
.
WEEK_START_WITH_SAT
?
0
:
week
;
}
/**
* DAY_OF_WEEK return 1 2 3 4 5 6 7,偏移了一位
* 获取日期所在月视图对应的起始偏移量
* Test pass
*
* @param year 年
* @param month 月
* @param weekStart 周起始
* @return 获取日期所在月视图对应的起始偏移量 the start diff with MonthView
*/
static
int
getMonthViewStartDiff
(
int
year
,
int
month
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
year
,
month
-
1
,
1
,
12
,
0
,
0
);
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
)
{
return
week
-
1
;
}
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_MON
)
{
return
week
==
1
?
6
:
week
-
weekStart
;
}
return
week
==
CalendarViewDelegate
.
WEEK_START_WITH_SAT
?
0
:
week
;
}
/**
* DAY_OF_WEEK return 1 2 3 4 5 6 7,偏移了一位
* 获取日期月份对应的结束偏移量,用于计算两个年份之间总共有多少周,不用于MonthView
* Test pass
*
* @param year 年
* @param month 月
* @param weekStart 周起始
* @return 获取日期月份对应的结束偏移量 the end diff in Month not MonthView
*/
static
int
getMonthEndDiff
(
int
year
,
int
month
,
int
weekStart
)
{
return
getMonthEndDiff
(
year
,
month
,
getMonthDaysCount
(
year
,
month
),
weekStart
);
}
/**
* DAY_OF_WEEK return 1 2 3 4 5 6 7,偏移了一位
* 获取日期月份对应的结束偏移量,用于计算两个年份之间总共有多少周,不用于MonthView
* Test pass
*
* @param year 年
* @param month 月
* @param weekStart 周起始
* @return 获取日期月份对应的结束偏移量 the end diff in Month not MonthView
*/
private
static
int
getMonthEndDiff
(
int
year
,
int
month
,
int
day
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
year
,
month
-
1
,
day
);
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
)
{
return
7
-
week
;
}
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_MON
)
{
return
week
==
1
?
0
:
7
-
week
+
1
;
}
return
week
==
7
?
6
:
7
-
week
-
1
;
}
/**
* 获取某个日期是星期几
* 测试通过
*
* @param calendar 某个日期
* @return 返回某个日期是星期几
*/
static
int
getWeekFormCalendar
(
Calendar
calendar
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
());
return
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
)
-
1
;
}
/**
* 获取周视图的切换默认选项位置 WeekView index
* 测试通过 test pass
*
* @param calendar calendar
* @param weekStart weekStart
* @return 获取周视图的切换默认选项位置
*/
static
int
getWeekViewIndexFromCalendar
(
Calendar
calendar
,
int
weekStart
)
{
return
getWeekViewStartDiff
(
calendar
.
getYear
(),
calendar
.
getMonth
(),
calendar
.
getDay
(),
weekStart
);
}
/**
* 是否在日期范围內
* 测试通过 test pass
*
* @param calendar calendar
* @param minYear minYear
* @param minYearDay 最小年份天
* @param minYearMonth minYearMonth
* @param maxYear maxYear
* @param maxYearMonth maxYearMonth
* @param maxYearDay 最大年份天
* @return 是否在日期范围內
*/
static
boolean
isCalendarInRange
(
Calendar
calendar
,
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
maxYear
,
int
maxYearMonth
,
int
maxYearDay
)
{
java
.
util
.
Calendar
c
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
c
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
c
.
set
(
minYear
,
minYearMonth
-
1
,
minYearDay
);
long
minTime
=
c
.
getTimeInMillis
();
c
.
set
(
maxYear
,
maxYearMonth
-
1
,
maxYearDay
);
long
maxTime
=
c
.
getTimeInMillis
();
c
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
());
long
curTime
=
c
.
getTimeInMillis
();
return
curTime
>=
minTime
&&
curTime
<=
maxTime
;
}
/**
* 获取两个日期之间一共有多少周,
* 注意周起始周一、周日、周六
* 测试通过 test pass
*
* @param minYear minYear 最小年份
* @param minYearMonth maxYear 最小年份月份
* @param minYearDay 最小年份天
* @param maxYear maxYear 最大年份
* @param maxYearMonth maxYear 最大年份月份
* @param maxYearDay 最大年份天
* @param weekStart 周起始
* @return 周数用于WeekViewPager itemCount
*/
public
static
int
getWeekCountBetweenBothCalendar
(
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
maxYear
,
int
maxYearMonth
,
int
maxYearDay
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
minYear
,
minYearMonth
-
1
,
minYearDay
);
long
minTimeMills
=
date
.
getTimeInMillis
();
//给定时间戳
int
preDiff
=
getWeekViewStartDiff
(
minYear
,
minYearMonth
,
minYearDay
,
weekStart
);
date
.
set
(
maxYear
,
maxYearMonth
-
1
,
maxYearDay
);
long
maxTimeMills
=
date
.
getTimeInMillis
();
//给定时间戳
int
nextDiff
=
getWeekViewEndDiff
(
maxYear
,
maxYearMonth
,
maxYearDay
,
weekStart
);
int
count
=
preDiff
+
nextDiff
;
int
c
=
(
int
)
((
maxTimeMills
-
minTimeMills
)
/
ONE_DAY
)
+
1
;
count
+=
c
;
return
count
/
7
;
}
/**
* 根据日期获取距离最小日期在第几周
* 用来设置 WeekView currentItem
* 测试通过 test pass
*
* @param calendar calendar
* @param minYear minYear 最小年份
* @param minYearMonth maxYear 最小年份月份
* @param minYearDay 最小年份天
* @param weekStart 周起始
* @return 返回两个年份中第几周 the WeekView currentItem
*/
public
static
int
getWeekFromCalendarStartWithMinCalendar
(
Calendar
calendar
,
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
minYear
,
minYearMonth
-
1
,
minYearDay
);
//起始日期
long
firstTimeMill
=
date
.
getTimeInMillis
();
//获得范围起始时间戳
int
preDiff
=
getWeekViewStartDiff
(
minYear
,
minYearMonth
,
minYearDay
,
weekStart
);
//范围起始的周偏移量
int
weekStartDiff
=
getWeekViewStartDiff
(
calendar
.
getYear
(),
calendar
.
getMonth
(),
calendar
.
getDay
(),
weekStart
);
//获取点击的日子在周视图的起始,为了兼容全球时区,最大日差为一天,如果周起始偏差weekStartDiff=0,则日期加1
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
weekStartDiff
==
0
?
calendar
.
getDay
()
+
1
:
calendar
.
getDay
());
long
curTimeMills
=
date
.
getTimeInMillis
();
//给定时间戳
int
c
=
(
int
)
((
curTimeMills
-
firstTimeMill
)
/
ONE_DAY
);
int
count
=
preDiff
+
c
;
return
count
/
7
+
1
;
}
/**
* 根据星期数和最小日期推算出该星期的第一天,
* 为了防止夏令时,导致的时间提前和延后1-2小时,导致日期出现误差1天,因此吧hourOfDay = 12
* //测试通过 Test pass
*
* @param minYear 最小年份如2017
* @param minYearMonth maxYear 最小年份月份,like : 2017-07
* @param minYearDay 最小年份天
* @param week 从最小年份minYear月minYearMonth 日1 开始的第几周 week > 0
* @param weekStart 周起始
* @return 该星期的第一天日期
*/
public
static
Calendar
getFirstCalendarStartWithMinCalendar
(
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
week
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
minYear
,
minYearMonth
-
1
,
minYearDay
,
12
,
0
);
//
long
firstTimeMills
=
date
.
getTimeInMillis
();
//获得起始时间戳
long
weekTimeMills
=
(
week
-
1
)
*
7
*
ONE_DAY
;
long
timeCountMills
=
weekTimeMills
+
firstTimeMills
;
date
.
setTimeInMillis
(
timeCountMills
);
int
startDiff
=
getWeekViewStartDiff
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
),
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
,
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
),
weekStart
);
timeCountMills
-=
startDiff
*
ONE_DAY
;
date
.
setTimeInMillis
(
timeCountMills
);
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
calendar
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
calendar
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
return
calendar
;
}
/**
* 是否在日期范围内
*
* @param calendar calendar
* @param delegate delegate
* @return 是否在日期范围内
*/
static
boolean
isCalendarInRange
(
Calendar
calendar
,
CalendarViewDelegate
delegate
)
{
return
isCalendarInRange
(
calendar
,
delegate
.
getMinYear
(),
delegate
.
getMinYearMonth
(),
delegate
.
getMinYearDay
(),
delegate
.
getMaxYear
(),
delegate
.
getMaxYearMonth
(),
delegate
.
getMaxYearDay
());
}
/**
* 是否在日期范围內
*
* @param year year
* @param month month
* @param minYear minYear
* @param minYearMonth minYearMonth
* @param maxYear maxYear
* @param maxYearMonth maxYearMonth
* @return 是否在日期范围內
*/
static
boolean
isMonthInRange
(
int
year
,
int
month
,
int
minYear
,
int
minYearMonth
,
int
maxYear
,
int
maxYearMonth
)
{
return
!(
year
<
minYear
||
year
>
maxYear
)
&&
!(
year
==
minYear
&&
month
<
minYearMonth
)
&&
!(
year
==
maxYear
&&
month
>
maxYearMonth
);
}
/**
* 运算 calendar1 - calendar2
* test Pass
*
* @param calendar1 calendar1
* @param calendar2 calendar2
* @return calendar1 - calendar2
*/
public
static
int
differ
(
Calendar
calendar1
,
Calendar
calendar2
)
{
if
(
calendar1
==
null
)
{
return
Integer
.
MIN_VALUE
;
}
if
(
calendar2
==
null
)
{
return
Integer
.
MAX_VALUE
;
}
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar1
.
getYear
(),
calendar1
.
getMonth
()
-
1
,
calendar1
.
getDay
(),
12
,
0
,
0
);
//
long
startTimeMills
=
date
.
getTimeInMillis
();
//获得起始时间戳
date
.
set
(
calendar2
.
getYear
(),
calendar2
.
getMonth
()
-
1
,
calendar2
.
getDay
(),
12
,
0
,
0
);
//
long
endTimeMills
=
date
.
getTimeInMillis
();
//获得结束时间戳
return
(
int
)
((
startTimeMills
-
endTimeMills
)
/
ONE_DAY
);
}
/**
* 比较日期大小
*
* @param minYear minYear
* @param minYearMonth minYearMonth
* @param minYearDay minYearDay
* @param maxYear maxYear
* @param maxYearMonth maxYearMonth
* @param maxYearDay maxYearDay
* @return <0 0 >0
*/
public
static
int
compareTo
(
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
maxYear
,
int
maxYearMonth
,
int
maxYearDay
)
{
Calendar
first
=
new
Calendar
();
first
.
setYear
(
minYear
);
first
.
setMonth
(
minYearMonth
);
first
.
setDay
(
minYearDay
);
Calendar
second
=
new
Calendar
();
second
.
setYear
(
maxYear
);
second
.
setMonth
(
maxYearMonth
);
second
.
setDay
(
maxYearDay
);
return
first
.
compareTo
(
second
);
}
/**
* 为月视图初始化日历
*
* @param year year
* @param month month
* @param currentDate currentDate
* @param weekStar weekStar
* @return 为月视图初始化日历项
*/
static
List
<
Calendar
>
initCalendarForMonthView
(
int
year
,
int
month
,
Calendar
currentDate
,
int
weekStar
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
year
,
month
-
1
,
1
);
int
mPreDiff
=
getMonthViewStartDiff
(
year
,
month
,
weekStar
);
//获取月视图其实偏移量
int
monthDayCount
=
getMonthDaysCount
(
year
,
month
);
//获取月份真实天数
int
preYear
,
preMonth
;
int
nextYear
,
nextMonth
;
int
size
=
42
;
List
<
Calendar
>
mItems
=
new
ArrayList
<>();
int
preMonthDaysCount
;
if
(
month
==
1
)
{
//如果是1月
preYear
=
year
-
1
;
preMonth
=
12
;
nextYear
=
year
;
nextMonth
=
month
+
1
;
preMonthDaysCount
=
mPreDiff
==
0
?
0
:
CalendarUtil
.
getMonthDaysCount
(
preYear
,
preMonth
);
}
else
if
(
month
==
12
)
{
//如果是12月
preYear
=
year
;
preMonth
=
month
-
1
;
nextYear
=
year
+
1
;
nextMonth
=
1
;
preMonthDaysCount
=
mPreDiff
==
0
?
0
:
CalendarUtil
.
getMonthDaysCount
(
preYear
,
preMonth
);
}
else
{
//平常
preYear
=
year
;
preMonth
=
month
-
1
;
nextYear
=
year
;
nextMonth
=
month
+
1
;
preMonthDaysCount
=
mPreDiff
==
0
?
0
:
CalendarUtil
.
getMonthDaysCount
(
preYear
,
preMonth
);
}
int
nextDay
=
1
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Calendar
calendarDate
=
new
Calendar
();
if
(
i
<
mPreDiff
)
{
calendarDate
.
setYear
(
preYear
);
calendarDate
.
setMonth
(
preMonth
);
calendarDate
.
setDay
(
preMonthDaysCount
-
mPreDiff
+
i
+
1
);
}
else
if
(
i
>=
monthDayCount
+
mPreDiff
)
{
calendarDate
.
setYear
(
nextYear
);
calendarDate
.
setMonth
(
nextMonth
);
calendarDate
.
setDay
(
nextDay
);
++
nextDay
;
}
else
{
calendarDate
.
setYear
(
year
);
calendarDate
.
setMonth
(
month
);
calendarDate
.
setCurrentMonth
(
true
);
calendarDate
.
setDay
(
i
-
mPreDiff
+
1
);
}
if
(
calendarDate
.
equals
(
currentDate
))
{
calendarDate
.
setCurrentDay
(
true
);
}
LunarCalendar
.
setupLunarCalendar
(
calendarDate
);
mItems
.
add
(
calendarDate
);
}
return
mItems
;
}
static
List
<
Calendar
>
getWeekCalendars
(
Calendar
calendar
,
CalendarViewDelegate
mDelegate
)
{
long
curTime
=
calendar
.
getTimeInMillis
();
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
(),
12
,
0
);
//
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
int
startDiff
;
if
(
mDelegate
.
getWeekStart
()
==
1
)
{
startDiff
=
week
-
1
;
}
else
if
(
mDelegate
.
getWeekStart
()
==
2
)
{
startDiff
=
week
==
1
?
6
:
week
-
mDelegate
.
getWeekStart
();
}
else
{
startDiff
=
week
==
7
?
0
:
week
;
}
curTime
-=
startDiff
*
ONE_DAY
;
java
.
util
.
Calendar
minCalendar
=
java
.
util
.
Calendar
.
getInstance
();
minCalendar
.
setTimeInMillis
(
curTime
);
Calendar
startCalendar
=
new
Calendar
();
startCalendar
.
setYear
(
minCalendar
.
get
(
java
.
util
.
Calendar
.
YEAR
));
startCalendar
.
setMonth
(
minCalendar
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
startCalendar
.
setDay
(
minCalendar
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
return
initCalendarForWeekView
(
startCalendar
,
mDelegate
,
mDelegate
.
getWeekStart
());
}
/**
* 生成周视图的7个item
*
* @param calendar 周视图的第一个日子calendar,所以往后推迟6天,生成周视图
* @param mDelegate mDelegate
* @param weekStart weekStart
* @return 生成周视图的7个item
*/
@SuppressWarnings
(
"unused"
)
static
List
<
Calendar
>
initCalendarForWeekView
(
Calendar
calendar
,
CalendarViewDelegate
mDelegate
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
//当天时间
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
(),
12
,
0
);
long
curDateMills
=
date
.
getTimeInMillis
();
//生成选择的日期时间戳
//int weekEndDiff = getWeekViewEndDiff(calendar.getYear(), calendar.getMonth(), calendar.getDay(), weekStart);
//weekEndDiff 例如周起始为周日1,当前为2020-04-01,周三,则weekEndDiff为本周结束相差今天三天,weekEndDiff=3
int
weekEndDiff
=
6
;
List
<
Calendar
>
mItems
=
new
ArrayList
<>();
date
.
setTimeInMillis
(
curDateMills
);
Calendar
selectCalendar
=
new
Calendar
();
selectCalendar
.
setYear
(
calendar
.
getYear
());
selectCalendar
.
setMonth
(
calendar
.
getMonth
());
selectCalendar
.
setDay
(
calendar
.
getDay
());
if
(
selectCalendar
.
equals
(
mDelegate
.
getCurrentDay
()))
{
selectCalendar
.
setCurrentDay
(
true
);
}
LunarCalendar
.
setupLunarCalendar
(
selectCalendar
);
selectCalendar
.
setCurrentMonth
(
true
);
mItems
.
add
(
selectCalendar
);
for
(
int
i
=
1
;
i
<=
weekEndDiff
;
i
++)
{
date
.
setTimeInMillis
(
curDateMills
+
i
*
ONE_DAY
);
Calendar
calendarDate
=
new
Calendar
();
calendarDate
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
calendarDate
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
calendarDate
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
if
(
calendarDate
.
equals
(
mDelegate
.
getCurrentDay
()))
{
calendarDate
.
setCurrentDay
(
true
);
}
LunarCalendar
.
setupLunarCalendar
(
calendarDate
);
calendarDate
.
setCurrentMonth
(
true
);
mItems
.
add
(
calendarDate
);
}
return
mItems
;
}
/**
* 单元测试通过
* 从选定的日期,获取周视图起始偏移量,用来生成周视图布局
*
* @param year year
* @param month month
* @param day day
* @param weekStart 周起始,1,2,7 日 一 六
* @return 获取周视图起始偏移量,用来生成周视图布局
*/
private
static
int
getWeekViewStartDiff
(
int
year
,
int
month
,
int
day
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
year
,
month
-
1
,
day
,
12
,
0
);
//
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
if
(
weekStart
==
1
)
{
return
week
-
1
;
}
if
(
weekStart
==
2
)
{
return
week
==
1
?
6
:
week
-
weekStart
;
}
return
week
==
7
?
0
:
week
;
}
/**
* 单元测试通过
* 从选定的日期,获取周视图结束偏移量,用来生成周视图布局
* 为了兼容DST,DST时区可能出现时间偏移1-2小时,从而导致凌晨时候实际获得的日期往前或者往后推移了一天,
* 日历没有时和分的概念,因此把日期的时间强制在12:00,可以避免DST兼容问题
*
* @param year year
* @param month month
* @param day day
* @param weekStart 周起始,1,2,7 日 一 六
* @return 获取周视图结束偏移量,用来生成周视图布局
*/
public
static
int
getWeekViewEndDiff
(
int
year
,
int
month
,
int
day
,
int
weekStart
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
year
,
month
-
1
,
day
,
12
,
0
);
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
if
(
weekStart
==
1
)
{
return
7
-
week
;
}
if
(
weekStart
==
2
)
{
return
week
==
1
?
0
:
7
-
week
+
1
;
}
return
week
==
7
?
6
:
7
-
week
-
1
;
}
/**
* 从月视图切换获得第一天的日期
* Test Pass 它是100%正确的
*
* @param position position
* @param delegate position
* @return 从月视图切换获得第一天的日期
*/
static
Calendar
getFirstCalendarFromMonthViewPager
(
int
position
,
CalendarViewDelegate
delegate
)
{
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
((
position
+
delegate
.
getMinYearMonth
()
-
1
)
/
12
+
delegate
.
getMinYear
());
calendar
.
setMonth
((
position
+
delegate
.
getMinYearMonth
()
-
1
)
%
12
+
1
);
if
(
delegate
.
getDefaultCalendarSelectDay
()
!=
CalendarViewDelegate
.
FIRST_DAY_OF_MONTH
)
{
int
monthDays
=
getMonthDaysCount
(
calendar
.
getYear
(),
calendar
.
getMonth
());
Calendar
indexCalendar
=
delegate
.
mIndexCalendar
;
calendar
.
setDay
(
indexCalendar
==
null
||
indexCalendar
.
getDay
()
==
0
?
1
:
monthDays
<
indexCalendar
.
getDay
()
?
monthDays
:
indexCalendar
.
getDay
());
}
else
{
calendar
.
setDay
(
1
);
}
if
(!
isCalendarInRange
(
calendar
,
delegate
))
{
if
(
isMinRangeEdge
(
calendar
,
delegate
))
{
calendar
=
delegate
.
getMinRangeCalendar
();
}
else
{
calendar
=
delegate
.
getMaxRangeCalendar
();
}
}
calendar
.
setCurrentMonth
(
calendar
.
getYear
()
==
delegate
.
getCurrentDay
().
getYear
()
&&
calendar
.
getMonth
()
==
delegate
.
getCurrentDay
().
getMonth
());
calendar
.
setCurrentDay
(
calendar
.
equals
(
delegate
.
getCurrentDay
()));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
return
calendar
;
}
/**
* 根据传入的日期获取边界访问日期,要么最大,要么最小
*
* @param calendar calendar
* @param delegate delegate
* @return 获取边界访问日期
*/
static
Calendar
getRangeEdgeCalendar
(
Calendar
calendar
,
CalendarViewDelegate
delegate
)
{
if
(
CalendarUtil
.
isCalendarInRange
(
delegate
.
getCurrentDay
(),
delegate
)
&&
delegate
.
getDefaultCalendarSelectDay
()
!=
CalendarViewDelegate
.
LAST_MONTH_VIEW_SELECT_DAY_IGNORE_CURRENT
)
{
return
delegate
.
createCurrentDate
();
}
if
(
isCalendarInRange
(
calendar
,
delegate
))
{
return
calendar
;
}
Calendar
minRangeCalendar
=
delegate
.
getMinRangeCalendar
();
if
(
minRangeCalendar
.
isSameMonth
(
calendar
))
{
return
delegate
.
getMinRangeCalendar
();
}
return
delegate
.
getMaxRangeCalendar
();
}
/**
* 是否是最小访问边界了
*
* @param calendar calendar
* @return 是否是最小访问边界了
*/
private
static
boolean
isMinRangeEdge
(
Calendar
calendar
,
CalendarViewDelegate
delegate
)
{
java
.
util
.
Calendar
c
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
c
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
c
.
set
(
delegate
.
getMinYear
(),
delegate
.
getMinYearMonth
()
-
1
,
delegate
.
getMinYearDay
(),
12
,
0
);
long
minTime
=
c
.
getTimeInMillis
();
c
.
set
(
calendar
.
getYear
(),
calendar
.
getMonth
()
-
1
,
calendar
.
getDay
(),
12
,
0
);
long
curTime
=
c
.
getTimeInMillis
();
return
curTime
<
minTime
;
}
/**
* dp转px
*
* @param context context
* @param dpValue dp
* @return px
*/
static
int
dipToPx
(
Context
context
,
float
dpValue
)
{
final
float
scale
=
context
.
getResources
().
getDisplayMetrics
().
density
;
return
(
int
)
(
dpValue
*
scale
+
0.5f
);
}
public
static
Calendar
getCalendarByLong
(
long
millis
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
setTimeInMillis
(
millis
);
Calendar
nextCalendar
=
new
Calendar
();
nextCalendar
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
nextCalendar
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
nextCalendar
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
return
nextCalendar
;
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CalendarView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.animation.Animator
;
import
android.animation.AnimatorListenerAdapter
;
import
android.content.Context
;
import
android.os.Bundle
;
import
android.os.Parcelable
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v4.view.ViewPager
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.animation.LinearInterpolator
;
import
android.widget.FrameLayout
;
import
com.sobot.widget.R
;
import
java.lang.reflect.Constructor
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TimeZone
;
/**
* 日历布局
* 各个类使用包权限,避免不必要的public
*/
@SuppressWarnings
({
"unused"
})
public
class
CalendarView
extends
FrameLayout
{
/**
* 抽取自定义属性
*/
private
final
CalendarViewDelegate
mDelegate
;
/**
* 自定义自适应高度的ViewPager
*/
private
MonthViewPager
mMonthPager
;
/**
* 日历周视图
*/
private
WeekViewPager
mWeekPager
;
/**
* 星期栏的线
*/
private
View
mWeekLine
;
/**
* 月份快速选取
*/
private
YearViewPager
mYearViewPager
;
/**
* 星期栏
*/
private
WeekBar
mWeekBar
;
/**
* 日历外部收缩布局
*/
CalendarLayout
mParentLayout
;
public
CalendarView
(
@NonNull
Context
context
)
{
this
(
context
,
null
);
}
public
CalendarView
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
mDelegate
=
new
CalendarViewDelegate
(
context
,
attrs
);
init
(
context
);
}
/**
* 初始化
*
* @param context context
*/
private
void
init
(
Context
context
)
{
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
sobot_layout_calendar_view
,
this
,
true
);
FrameLayout
frameContent
=
findViewById
(
R
.
id
.
frameContent
);
this
.
mWeekPager
=
findViewById
(
R
.
id
.
vp_week
);
this
.
mWeekPager
.
setup
(
mDelegate
);
try
{
Constructor
constructor
=
mDelegate
.
getWeekBarClass
().
getConstructor
(
Context
.
class
);
mWeekBar
=
(
WeekBar
)
constructor
.
newInstance
(
getContext
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
frameContent
.
addView
(
mWeekBar
,
2
);
mWeekBar
.
setup
(
mDelegate
);
mWeekBar
.
onWeekStartChange
(
mDelegate
.
getWeekStart
());
this
.
mWeekLine
=
findViewById
(
R
.
id
.
line
);
this
.
mWeekLine
.
setBackgroundColor
(
mDelegate
.
getWeekLineBackground
());
LayoutParams
lineParams
=
(
LayoutParams
)
this
.
mWeekLine
.
getLayoutParams
();
lineParams
.
setMargins
(
mDelegate
.
getWeekLineMargin
(),
mDelegate
.
getWeekBarHeight
(),
mDelegate
.
getWeekLineMargin
(),
0
);
this
.
mWeekLine
.
setLayoutParams
(
lineParams
);
this
.
mMonthPager
=
findViewById
(
R
.
id
.
vp_month
);
this
.
mMonthPager
.
mWeekPager
=
mWeekPager
;
this
.
mMonthPager
.
mWeekBar
=
mWeekBar
;
LayoutParams
params
=
(
LayoutParams
)
this
.
mMonthPager
.
getLayoutParams
();
params
.
setMargins
(
0
,
mDelegate
.
getWeekBarHeight
()
+
CalendarUtil
.
dipToPx
(
context
,
1
),
0
,
0
);
mWeekPager
.
setLayoutParams
(
params
);
mYearViewPager
=
findViewById
(
R
.
id
.
selectLayout
);
mYearViewPager
.
setPadding
(
mDelegate
.
getYearViewPaddingLeft
(),
0
,
mDelegate
.
getYearViewPaddingRight
(),
0
);
mYearViewPager
.
setBackgroundColor
(
mDelegate
.
getYearViewBackground
());
mYearViewPager
.
addOnPageChangeListener
(
new
ViewPager
.
OnPageChangeListener
()
{
@Override
public
void
onPageScrolled
(
int
position
,
float
positionOffset
,
int
positionOffsetPixels
)
{
}
@Override
public
void
onPageSelected
(
int
position
)
{
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
return
;
}
if
(
mDelegate
.
mYearChangeListener
!=
null
)
{
mDelegate
.
mYearChangeListener
.
onYearChange
(
position
+
mDelegate
.
getMinYear
());
}
}
@Override
public
void
onPageScrollStateChanged
(
int
state
)
{
}
});
mDelegate
.
mInnerListener
=
new
OnInnerDateSelectedListener
()
{
/**
* 月视图选择事件
* @param calendar calendar
* @param isClick 是否是点击
*/
@Override
public
void
onMonthDateSelected
(
Calendar
calendar
,
boolean
isClick
)
{
if
(
calendar
.
getYear
()
==
mDelegate
.
getCurrentDay
().
getYear
()
&&
calendar
.
getMonth
()
==
mDelegate
.
getCurrentDay
().
getMonth
()
&&
mMonthPager
.
getCurrentItem
()
!=
mDelegate
.
mCurrentMonthViewItem
)
{
return
;
}
mDelegate
.
mIndexCalendar
=
calendar
;
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
||
isClick
)
{
mDelegate
.
mSelectedCalendar
=
calendar
;
}
mWeekPager
.
updateSelected
(
mDelegate
.
mIndexCalendar
,
false
);
mMonthPager
.
updateSelected
();
if
(
mWeekBar
!=
null
&&
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
||
isClick
))
{
mWeekBar
.
onDateSelected
(
calendar
,
mDelegate
.
getWeekStart
(),
isClick
);
}
}
/**
* 周视图选择事件
* @param calendar calendar
* @param isClick 是否是点击
*/
@Override
public
void
onWeekDateSelected
(
Calendar
calendar
,
boolean
isClick
)
{
mDelegate
.
mIndexCalendar
=
calendar
;
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
||
isClick
||
mDelegate
.
mIndexCalendar
.
equals
(
mDelegate
.
mSelectedCalendar
))
{
mDelegate
.
mSelectedCalendar
=
calendar
;
}
int
y
=
calendar
.
getYear
()
-
mDelegate
.
getMinYear
();
int
position
=
12
*
y
+
mDelegate
.
mIndexCalendar
.
getMonth
()
-
mDelegate
.
getMinYearMonth
();
mWeekPager
.
updateSingleSelect
();
mMonthPager
.
setCurrentItem
(
position
,
false
);
mMonthPager
.
updateSelected
();
if
(
mWeekBar
!=
null
&&
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
||
isClick
||
mDelegate
.
mIndexCalendar
.
equals
(
mDelegate
.
mSelectedCalendar
)))
{
mWeekBar
.
onDateSelected
(
calendar
,
mDelegate
.
getWeekStart
(),
isClick
);
}
}
};
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
if
(
isInRange
(
mDelegate
.
getCurrentDay
()))
{
mDelegate
.
mSelectedCalendar
=
mDelegate
.
createCurrentDate
();
}
else
{
mDelegate
.
mSelectedCalendar
=
mDelegate
.
getMinRangeCalendar
();
}
}
else
{
mDelegate
.
mSelectedCalendar
=
new
Calendar
();
}
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
(),
false
);
mMonthPager
.
setup
(
mDelegate
);
mMonthPager
.
setCurrentItem
(
mDelegate
.
mCurrentMonthViewItem
);
mYearViewPager
.
setOnMonthSelectedListener
(
new
YearRecyclerView
.
OnMonthSelectedListener
()
{
@Override
public
void
onMonthSelected
(
int
year
,
int
month
)
{
int
position
=
12
*
(
year
-
mDelegate
.
getMinYear
())
+
month
-
mDelegate
.
getMinYearMonth
();
closeSelectLayout
(
position
);
mDelegate
.
isShowYearSelectedLayout
=
false
;
}
});
mYearViewPager
.
setup
(
mDelegate
);
mWeekPager
.
updateSelected
(
mDelegate
.
createCurrentDate
(),
false
);
}
/**
* 设置日期范围
*
* @param minYear 最小年份
* @param minYearMonth 最小年份对应月份
* @param minYearDay 最小年份对应天
* @param maxYear 最大月份
* @param maxYearMonth 最大月份对应月份
* @param maxYearDay 最大月份对应天
*/
public
void
setRange
(
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
maxYear
,
int
maxYearMonth
,
int
maxYearDay
,
String
zone
)
{
if
(
CalendarUtil
.
compareTo
(
minYear
,
minYearMonth
,
minYearDay
,
maxYear
,
maxYearMonth
,
maxYearDay
)
>
0
)
{
return
;
}
mDelegate
.
setRange
(
minYear
,
minYearMonth
,
minYearDay
,
maxYear
,
maxYearMonth
,
maxYearDay
);
mWeekPager
.
notifyDataSetChanged
();
mYearViewPager
.
notifyDataSetChanged
();
mMonthPager
.
notifyDataSetChanged
();
if
(!
isInRange
(
mDelegate
.
mSelectedCalendar
))
{
mDelegate
.
mSelectedCalendar
=
mDelegate
.
getMinRangeCalendar
();
mDelegate
.
updateSelectCalendarScheme
();
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
}
mWeekPager
.
updateRange
();
mMonthPager
.
updateRange
();
mYearViewPager
.
updateRange
();
if
(!
TextUtils
.
isEmpty
(
zone
)){
setZone
(
zone
);
}
}
/**
* 获取当天
*
* @return 返回今天
*/
public
int
getCurDay
()
{
return
mDelegate
.
getCurrentDay
().
getDay
();
}
/**
* 获取本月
*
* @return 返回本月
*/
public
int
getCurMonth
()
{
return
mDelegate
.
getCurrentDay
().
getMonth
();
}
/**
* 获取本年
*
* @return 返回本年
*/
public
int
getCurYear
()
{
return
mDelegate
.
getCurrentDay
().
getYear
();
}
/**
* 打开日历年月份快速选择
*
* @param year 年
*/
public
void
showYearSelectLayout
(
final
int
year
)
{
showSelectLayout
(
year
);
}
/**
* 打开日历年月份快速选择
* 请使用 showYearSelectLayout(final int year) 代替,这个没什么,越来越规范
*
* @param year 年
*/
private
void
showSelectLayout
(
final
int
year
)
{
if
(
mParentLayout
!=
null
&&
mParentLayout
.
mContentView
!=
null
)
{
if
(!
mParentLayout
.
isExpand
())
{
mParentLayout
.
expand
();
//return;
}
}
mWeekPager
.
setVisibility
(
GONE
);
mDelegate
.
isShowYearSelectedLayout
=
true
;
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
hideContentView
();
}
mWeekBar
.
animate
()
.
translationY
(-
mWeekBar
.
getHeight
())
.
setInterpolator
(
new
LinearInterpolator
())
.
setDuration
(
260
)
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
mWeekBar
.
setVisibility
(
GONE
);
mYearViewPager
.
setVisibility
(
VISIBLE
);
mYearViewPager
.
scrollToYear
(
year
,
false
);
if
(
mParentLayout
!=
null
&&
mParentLayout
.
mContentView
!=
null
)
{
mParentLayout
.
expand
();
}
}
});
mMonthPager
.
animate
()
.
scaleX
(
0
)
.
scaleY
(
0
)
.
setDuration
(
260
)
.
setInterpolator
(
new
LinearInterpolator
())
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
if
(
mDelegate
.
mYearViewChangeListener
!=
null
)
{
mDelegate
.
mYearViewChangeListener
.
onYearViewChange
(
false
);
}
}
});
}
/**
* 年月份选择视图是否打开
*
* @return true or false
*/
public
boolean
isYearSelectLayoutVisible
()
{
return
mYearViewPager
.
getVisibility
()
==
VISIBLE
;
}
/**
* 关闭年月视图选择布局
*/
public
void
closeYearSelectLayout
()
{
if
(
mYearViewPager
.
getVisibility
()
==
GONE
)
{
return
;
}
int
position
=
12
*
(
mDelegate
.
mSelectedCalendar
.
getYear
()
-
mDelegate
.
getMinYear
())
+
mDelegate
.
mSelectedCalendar
.
getMonth
()
-
mDelegate
.
getMinYearMonth
();
closeSelectLayout
(
position
);
mDelegate
.
isShowYearSelectedLayout
=
false
;
}
/**
* 关闭日历布局,同时会滚动到指定的位置
*
* @param position 某一年
*/
private
void
closeSelectLayout
(
final
int
position
)
{
mYearViewPager
.
setVisibility
(
GONE
);
mWeekBar
.
setVisibility
(
VISIBLE
);
if
(
position
==
mMonthPager
.
getCurrentItem
())
{
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_SINGLE
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
mDelegate
.
mSelectedCalendar
,
false
);
}
}
else
{
mMonthPager
.
setCurrentItem
(
position
,
false
);
}
mWeekBar
.
animate
()
.
translationY
(
0
)
.
setInterpolator
(
new
LinearInterpolator
())
.
setDuration
(
280
)
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
mWeekBar
.
setVisibility
(
VISIBLE
);
}
});
mMonthPager
.
animate
()
.
scaleX
(
1
)
.
scaleY
(
1
)
.
setDuration
(
180
)
.
setInterpolator
(
new
LinearInterpolator
())
.
setListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
if
(
mDelegate
.
mYearViewChangeListener
!=
null
)
{
mDelegate
.
mYearViewChangeListener
.
onYearViewChange
(
true
);
}
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
showContentView
();
if
(
mParentLayout
.
isExpand
())
{
mMonthPager
.
setVisibility
(
VISIBLE
);
}
else
{
mWeekPager
.
setVisibility
(
VISIBLE
);
mParentLayout
.
shrink
();
}
}
else
{
mMonthPager
.
setVisibility
(
VISIBLE
);
}
mMonthPager
.
clearAnimation
();
}
});
}
/**
* 滚动到当前
*/
public
void
scrollToCurrent
()
{
scrollToCurrent
(
false
);
}
/**
* 滚动到当前
*
* @param smoothScroll smoothScroll
*/
public
void
scrollToCurrent
(
boolean
smoothScroll
)
{
if
(!
isInRange
(
mDelegate
.
getCurrentDay
()))
{
return
;
}
Calendar
calendar
=
mDelegate
.
createCurrentDate
();
if
(
mDelegate
.
mCalendarInterceptListener
!=
null
&&
mDelegate
.
mCalendarInterceptListener
.
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
false
);
return
;
}
mDelegate
.
mSelectedCalendar
=
mDelegate
.
createCurrentDate
();
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
mDelegate
.
updateSelectCalendarScheme
();
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
(),
false
);
if
(
mMonthPager
.
getVisibility
()
==
VISIBLE
)
{
mMonthPager
.
scrollToCurrent
(
smoothScroll
);
mWeekPager
.
updateSelected
(
mDelegate
.
mIndexCalendar
,
false
);
}
else
{
mWeekPager
.
scrollToCurrent
(
smoothScroll
);
}
mYearViewPager
.
scrollToYear
(
mDelegate
.
getCurrentDay
().
getYear
(),
smoothScroll
);
}
/**
* 滚动到下一个月
*/
public
void
scrollToNext
()
{
scrollToNext
(
false
);
}
/**
* 滚动到下一个月
*
* @param smoothScroll smoothScroll
*/
public
void
scrollToNext
(
boolean
smoothScroll
)
{
if
(
isYearSelectLayoutVisible
())
{
mYearViewPager
.
setCurrentItem
(
mYearViewPager
.
getCurrentItem
()
+
1
,
smoothScroll
);
}
else
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
mWeekPager
.
setCurrentItem
(
mWeekPager
.
getCurrentItem
()
+
1
,
smoothScroll
);
}
else
{
mMonthPager
.
setCurrentItem
(
mMonthPager
.
getCurrentItem
()
+
1
,
smoothScroll
);
}
}
/**
* 滚动到上一个月
*/
public
void
scrollToPre
()
{
scrollToPre
(
false
);
}
/**
* 滚动到上一个月
*
* @param smoothScroll smoothScroll
*/
public
void
scrollToPre
(
boolean
smoothScroll
)
{
if
(
isYearSelectLayoutVisible
())
{
mYearViewPager
.
setCurrentItem
(
mYearViewPager
.
getCurrentItem
()
-
1
,
smoothScroll
);
}
else
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
mWeekPager
.
setCurrentItem
(
mWeekPager
.
getCurrentItem
()
-
1
,
smoothScroll
);
}
else
{
mMonthPager
.
setCurrentItem
(
mMonthPager
.
getCurrentItem
()
-
1
,
smoothScroll
);
}
}
/**
* 滚动到选择的日历
*/
public
void
scrollToSelectCalendar
()
{
if
(!
mDelegate
.
mSelectedCalendar
.
isAvailable
())
{
return
;
}
scrollToCalendar
(
mDelegate
.
mSelectedCalendar
.
getYear
(),
mDelegate
.
mSelectedCalendar
.
getMonth
(),
mDelegate
.
mSelectedCalendar
.
getDay
(),
false
,
true
);
}
/**
* 滚动到指定日期
*
* @param year year
* @param month month
* @param day day
*/
public
void
scrollToCalendar
(
int
year
,
int
month
,
int
day
)
{
scrollToCalendar
(
year
,
month
,
day
,
false
,
true
);
}
/**
* 滚动到指定日期
*
* @param year year
* @param month month
* @param day day
* @param smoothScroll smoothScroll
*/
public
void
scrollToCalendar
(
int
year
,
int
month
,
int
day
,
boolean
smoothScroll
)
{
scrollToCalendar
(
year
,
month
,
day
,
smoothScroll
,
true
);
}
/**
* 滚动到指定日期
*
* @param year year
* @param month month
* @param day day
* @param smoothScroll smoothScroll
* @param invokeListener 调用日期事件
*/
public
void
scrollToCalendar
(
int
year
,
int
month
,
int
day
,
boolean
smoothScroll
,
boolean
invokeListener
)
{
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
year
);
calendar
.
setMonth
(
month
);
calendar
.
setDay
(
day
);
if
(!
calendar
.
isAvailable
())
{
return
;
}
if
(!
isInRange
(
calendar
))
{
return
;
}
if
(
mDelegate
.
mCalendarInterceptListener
!=
null
&&
mDelegate
.
mCalendarInterceptListener
.
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
false
);
return
;
}
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
mWeekPager
.
scrollToCalendar
(
year
,
month
,
day
,
smoothScroll
,
invokeListener
);
}
else
{
mMonthPager
.
scrollToCalendar
(
year
,
month
,
day
,
smoothScroll
,
invokeListener
);
}
}
/**
* 滚动到某一年
*
* @param year 快速滚动的年份
*/
public
void
scrollToYear
(
int
year
)
{
scrollToYear
(
year
,
false
);
}
/**
* 滚动到某一年
*
* @param year 快速滚动的年份
* @param smoothScroll smoothScroll
*/
public
void
scrollToYear
(
int
year
,
boolean
smoothScroll
)
{
if
(
mYearViewPager
.
getVisibility
()
!=
VISIBLE
)
{
return
;
}
mYearViewPager
.
scrollToYear
(
year
,
smoothScroll
);
}
/**
* 设置月视图是否可滚动
*
* @param monthViewScrollable 设置月视图是否可滚动
*/
public
final
void
setMonthViewScrollable
(
boolean
monthViewScrollable
)
{
mDelegate
.
setMonthViewScrollable
(
monthViewScrollable
);
}
/**
* 设置周视图是否可滚动
*
* @param weekViewScrollable 设置周视图是否可滚动
*/
public
final
void
setWeekViewScrollable
(
boolean
weekViewScrollable
)
{
mDelegate
.
setWeekViewScrollable
(
weekViewScrollable
);
}
/**
* 设置年视图是否可滚动
*
* @param yearViewScrollable 设置年视图是否可滚动
*/
public
final
void
setYearViewScrollable
(
boolean
yearViewScrollable
)
{
mDelegate
.
setYearViewScrollable
(
yearViewScrollable
);
}
public
final
void
setDefaultMonthViewSelectDay
()
{
mDelegate
.
setDefaultCalendarSelectDay
(
CalendarViewDelegate
.
FIRST_DAY_OF_MONTH
);
}
public
final
void
setLastMonthViewSelectDay
()
{
mDelegate
.
setDefaultCalendarSelectDay
(
CalendarViewDelegate
.
LAST_MONTH_VIEW_SELECT_DAY
);
}
public
final
void
setLastMonthViewSelectDayIgnoreCurrent
()
{
mDelegate
.
setDefaultCalendarSelectDay
(
CalendarViewDelegate
.
LAST_MONTH_VIEW_SELECT_DAY_IGNORE_CURRENT
);
}
public
final
void
setZone
(
String
zone
)
{
this
.
zone
=
zone
;
mDelegate
.
setZone
(
zone
);
}
private
String
zone
;
/**
* 清除选择范围
*/
public
final
void
clearSelectRange
()
{
mDelegate
.
clearSelectRange
();
mMonthPager
.
clearSelectRange
();
mWeekPager
.
clearSelectRange
();
}
/**
* 清除单选
*/
public
final
void
clearSingleSelect
()
{
mDelegate
.
mSelectedCalendar
=
new
Calendar
();
mMonthPager
.
clearSingleSelect
();
mWeekPager
.
clearSingleSelect
();
}
/**
* 清除多选
*/
public
final
void
clearMultiSelect
()
{
mDelegate
.
mSelectedCalendars
.
clear
();
mMonthPager
.
clearMultiSelect
();
mWeekPager
.
clearMultiSelect
();
}
/**
* 添加选择
*
* @param calendars calendars
*/
public
final
void
putMultiSelect
(
Calendar
...
calendars
)
{
if
(
calendars
==
null
||
calendars
.
length
==
0
)
{
return
;
}
for
(
Calendar
calendar
:
calendars
)
{
if
(
calendar
==
null
||
mDelegate
.
mSelectedCalendars
.
containsKey
(
calendar
.
toString
()))
{
continue
;
}
mDelegate
.
mSelectedCalendars
.
put
(
calendar
.
toString
(),
calendar
);
}
update
();
}
/**
* 清楚一些多选日期
*
* @param calendars calendars
*/
@SuppressWarnings
(
"RedundantCollectionOperation"
)
public
final
void
removeMultiSelect
(
Calendar
...
calendars
)
{
if
(
calendars
==
null
||
calendars
.
length
==
0
)
{
return
;
}
for
(
Calendar
calendar
:
calendars
)
{
if
(
calendar
==
null
)
{
continue
;
}
if
(
mDelegate
.
mSelectedCalendars
.
containsKey
(
calendar
.
toString
()))
{
mDelegate
.
mSelectedCalendars
.
remove
(
calendar
.
toString
());
}
}
update
();
}
public
final
List
<
Calendar
>
getMultiSelectCalendars
()
{
List
<
Calendar
>
calendars
=
new
ArrayList
<>();
if
(
mDelegate
.
mSelectedCalendars
.
size
()
==
0
)
{
return
calendars
;
}
calendars
.
addAll
(
mDelegate
.
mSelectedCalendars
.
values
());
Collections
.
sort
(
calendars
);
return
calendars
;
}
/**
* 获取选中范围
*
* @return return
*/
public
final
List
<
Calendar
>
getSelectCalendarRange
()
{
return
mDelegate
.
getSelectCalendarRange
();
}
/**
* 设置月视图项高度
*
* @param calendarItemHeight MonthView item height
*/
public
final
void
setCalendarItemHeight
(
int
calendarItemHeight
)
{
if
(
mDelegate
.
getCalendarItemHeight
()
==
calendarItemHeight
)
{
return
;
}
mDelegate
.
setCalendarItemHeight
(
calendarItemHeight
);
mMonthPager
.
updateItemHeight
();
mWeekPager
.
updateItemHeight
();
if
(
mParentLayout
==
null
)
{
return
;
}
mParentLayout
.
updateCalendarItemHeight
();
}
/**
* 设置月视图
*
* @param cls MonthView.class
*/
public
final
void
setMonthView
(
Class
<?>
cls
)
{
if
(
cls
==
null
)
{
return
;
}
if
(
mDelegate
.
getMonthViewClass
().
equals
(
cls
))
{
return
;
}
mDelegate
.
setMonthViewClass
(
cls
);
mMonthPager
.
updateMonthViewClass
();
}
/**
* 设置周视图
*
* @param cls WeekView.class
*/
public
final
void
setWeekView
(
Class
<?>
cls
)
{
if
(
cls
==
null
)
{
return
;
}
if
(
mDelegate
.
getWeekBarClass
().
equals
(
cls
))
{
return
;
}
mDelegate
.
setWeekViewClass
(
cls
);
mWeekPager
.
updateWeekViewClass
();
}
/**
* 设置周栏视图
*
* @param cls WeekBar.class
*/
public
final
void
setWeekBar
(
Class
<?>
cls
)
{
if
(
cls
==
null
)
{
return
;
}
if
(
mDelegate
.
getWeekBarClass
().
equals
(
cls
))
{
return
;
}
mDelegate
.
setWeekBarClass
(
cls
);
FrameLayout
frameContent
=
findViewById
(
R
.
id
.
frameContent
);
frameContent
.
removeView
(
mWeekBar
);
try
{
Constructor
constructor
=
cls
.
getConstructor
(
Context
.
class
);
mWeekBar
=
(
WeekBar
)
constructor
.
newInstance
(
getContext
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
frameContent
.
addView
(
mWeekBar
,
2
);
mWeekBar
.
setup
(
mDelegate
);
mWeekBar
.
onWeekStartChange
(
mDelegate
.
getWeekStart
());
this
.
mMonthPager
.
mWeekBar
=
mWeekBar
;
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
(),
false
);
}
/**
* 添加日期拦截事件
* 使用此方法,只能基于select_mode = single_mode
* 否则的话,如果标记全部日期为不可点击,那是没有意义的,
* 框架本身也不可能在滑动的过程中全部去判断每个日期的可点击性
*
* @param listener listener
*/
public
final
void
setOnCalendarInterceptListener
(
OnCalendarInterceptListener
listener
)
{
if
(
listener
==
null
)
{
mDelegate
.
mCalendarInterceptListener
=
null
;
}
if
(
listener
==
null
||
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
return
;
}
mDelegate
.
mCalendarInterceptListener
=
listener
;
if
(!
listener
.
onCalendarIntercept
(
mDelegate
.
mSelectedCalendar
))
{
return
;
}
mDelegate
.
mSelectedCalendar
=
new
Calendar
();
}
/**
* 点击视图Padding位置的事件
*
* @param listener listener
*/
public
final
void
setOnClickCalendarPaddingListener
(
OnClickCalendarPaddingListener
listener
)
{
if
(
listener
==
null
)
{
mDelegate
.
mClickCalendarPaddingListener
=
null
;
}
if
(
listener
==
null
)
{
return
;
}
mDelegate
.
mClickCalendarPaddingListener
=
listener
;
}
/**
* 年份改变事件
*
* @param listener listener
*/
public
void
setOnYearChangeListener
(
OnYearChangeListener
listener
)
{
this
.
mDelegate
.
mYearChangeListener
=
listener
;
}
/**
* 月份改变事件
*
* @param listener listener
*/
public
void
setOnMonthChangeListener
(
OnMonthChangeListener
listener
)
{
this
.
mDelegate
.
mMonthChangeListener
=
listener
;
}
/**
* 周视图切换监听
*
* @param listener listener
*/
public
void
setOnWeekChangeListener
(
OnWeekChangeListener
listener
)
{
this
.
mDelegate
.
mWeekChangeListener
=
listener
;
}
/**
* 日期选择事件
*
* @param listener listener
*/
public
void
setOnCalendarSelectListener
(
OnCalendarSelectListener
listener
)
{
this
.
mDelegate
.
mCalendarSelectListener
=
listener
;
if
(
mDelegate
.
mCalendarSelectListener
==
null
)
{
return
;
}
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
return
;
}
if
(!
isInRange
(
mDelegate
.
mSelectedCalendar
))
{
return
;
}
mDelegate
.
updateSelectCalendarScheme
();
}
/**
* 日期选择事件
*
* @param listener listener
*/
public
final
void
setOnCalendarRangeSelectListener
(
OnCalendarRangeSelectListener
listener
)
{
this
.
mDelegate
.
mCalendarRangeSelectListener
=
listener
;
}
/**
* 日期多选事件
*
* @param listener listener
*/
public
final
void
setOnCalendarMultiSelectListener
(
OnCalendarMultiSelectListener
listener
)
{
this
.
mDelegate
.
mCalendarMultiSelectListener
=
listener
;
}
/**
* 设置最小范围和最大访问,default:minRange = -1,maxRange = -1 没有限制
*
* @param minRange minRange
* @param maxRange maxRange
*/
public
final
void
setSelectRange
(
int
minRange
,
int
maxRange
)
{
if
(
minRange
>
maxRange
)
{
return
;
}
mDelegate
.
setSelectRange
(
minRange
,
maxRange
);
}
public
final
void
setSelectStartCalendar
(
int
startYear
,
int
startMonth
,
int
startDay
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
Calendar
startCalendar
=
new
Calendar
();
startCalendar
.
setYear
(
startYear
);
startCalendar
.
setMonth
(
startMonth
);
startCalendar
.
setDay
(
startDay
);
setSelectStartCalendar
(
startCalendar
);
}
public
final
void
setSelectStartCalendar
(
Calendar
startCalendar
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
if
(
startCalendar
==
null
)
{
return
;
}
if
(!
isInRange
(
startCalendar
))
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
startCalendar
,
true
);
}
return
;
}
if
(
onCalendarIntercept
(
startCalendar
))
{
if
(
mDelegate
.
mCalendarInterceptListener
!=
null
)
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
startCalendar
,
false
);
}
return
;
}
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
mDelegate
.
mSelectedStartRangeCalendar
=
startCalendar
;
scrollToCalendar
(
startCalendar
.
getYear
(),
startCalendar
.
getMonth
(),
startCalendar
.
getDay
());
}
public
final
void
setSelectEndCalendar
(
int
endYear
,
int
endMonth
,
int
endDay
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
)
{
return
;
}
Calendar
endCalendar
=
new
Calendar
();
endCalendar
.
setYear
(
endYear
);
endCalendar
.
setMonth
(
endMonth
);
endCalendar
.
setDay
(
endDay
);
setSelectEndCalendar
(
endCalendar
);
}
public
final
void
setSelectEndCalendar
(
Calendar
endCalendar
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
)
{
return
;
}
setSelectCalendarRange
(
mDelegate
.
mSelectedStartRangeCalendar
,
endCalendar
);
}
/**
* 直接指定选择范围,set select calendar range
*
* @param startYear startYear
* @param startMonth startMonth
* @param startDay startDay
* @param endYear endYear
* @param endMonth endMonth
* @param endDay endDay
*/
public
final
void
setSelectCalendarRange
(
int
startYear
,
int
startMonth
,
int
startDay
,
int
endYear
,
int
endMonth
,
int
endDay
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
Calendar
startCalendar
=
new
Calendar
();
startCalendar
.
setYear
(
startYear
);
startCalendar
.
setMonth
(
startMonth
);
startCalendar
.
setDay
(
startDay
);
Calendar
endCalendar
=
new
Calendar
();
endCalendar
.
setYear
(
endYear
);
endCalendar
.
setMonth
(
endMonth
);
endCalendar
.
setDay
(
endDay
);
setSelectCalendarRange
(
startCalendar
,
endCalendar
);
}
/**
* 设置选择日期范围
*
* @param startCalendar startCalendar
* @param endCalendar endCalendar
*/
public
final
void
setSelectCalendarRange
(
Calendar
startCalendar
,
Calendar
endCalendar
)
{
if
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
if
(
startCalendar
==
null
||
endCalendar
==
null
)
{
return
;
}
if
(
onCalendarIntercept
(
startCalendar
))
{
if
(
mDelegate
.
mCalendarInterceptListener
!=
null
)
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
startCalendar
,
false
);
}
return
;
}
if
(
onCalendarIntercept
(
endCalendar
))
{
if
(
mDelegate
.
mCalendarInterceptListener
!=
null
)
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
endCalendar
,
false
);
}
return
;
}
int
minDiffer
=
endCalendar
.
differ
(
startCalendar
);
if
(
minDiffer
<
0
)
{
return
;
}
if
(!
isInRange
(
startCalendar
)
||
!
isInRange
(
endCalendar
))
{
return
;
}
//优先判断各种直接return的情况,减少代码深度
if
(
mDelegate
.
getMinSelectRange
()
!=
-
1
&&
mDelegate
.
getMinSelectRange
()
>
minDiffer
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
endCalendar
,
true
);
}
return
;
}
else
if
(
mDelegate
.
getMaxSelectRange
()
!=
-
1
&&
mDelegate
.
getMaxSelectRange
()
<
minDiffer
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
endCalendar
,
false
);
}
return
;
}
if
(
mDelegate
.
getMinSelectRange
()
==
-
1
&&
minDiffer
==
0
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
startCalendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarRangeSelect
(
startCalendar
,
false
);
}
scrollToCalendar
(
startCalendar
.
getYear
(),
startCalendar
.
getMonth
(),
startCalendar
.
getDay
());
return
;
}
mDelegate
.
mSelectedStartRangeCalendar
=
startCalendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
endCalendar
;
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarRangeSelect
(
startCalendar
,
false
);
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarRangeSelect
(
endCalendar
,
true
);
}
scrollToCalendar
(
startCalendar
.
getYear
(),
startCalendar
.
getMonth
(),
startCalendar
.
getDay
());
}
/**
* 是否拦截日期,此设置续设置mCalendarInterceptListener
*
* @param calendar calendar
* @return 是否拦截日期
*/
protected
final
boolean
onCalendarIntercept
(
Calendar
calendar
)
{
return
mDelegate
.
mCalendarInterceptListener
!=
null
&&
mDelegate
.
mCalendarInterceptListener
.
onCalendarIntercept
(
calendar
);
}
/**
* 获得最大多选数量
*
* @return 获得最大多选数量
*/
public
final
int
getMaxMultiSelectSize
()
{
return
mDelegate
.
getMaxMultiSelectSize
();
}
/**
* 设置最大多选数量
*
* @param maxMultiSelectSize 最大多选数量
*/
public
final
void
setMaxMultiSelectSize
(
int
maxMultiSelectSize
)
{
mDelegate
.
setMaxMultiSelectSize
(
maxMultiSelectSize
);
}
/**
* 最小选择范围
*
* @return 最小选择范围
*/
public
final
int
getMinSelectRange
()
{
return
mDelegate
.
getMinSelectRange
();
}
/**
* 最大选择范围
*
* @return 最大选择范围
*/
public
final
int
getMaxSelectRange
()
{
return
mDelegate
.
getMaxSelectRange
();
}
/**
* 日期长按事件
*
* @param listener listener
*/
public
void
setOnCalendarLongClickListener
(
OnCalendarLongClickListener
listener
)
{
this
.
mDelegate
.
mCalendarLongClickListener
=
listener
;
}
/**
* 日期长按事件
*
* @param preventLongPressedSelect 防止长按选择日期
* @param listener listener
*/
public
void
setOnCalendarLongClickListener
(
OnCalendarLongClickListener
listener
,
boolean
preventLongPressedSelect
)
{
this
.
mDelegate
.
mCalendarLongClickListener
=
listener
;
this
.
mDelegate
.
setPreventLongPressedSelected
(
preventLongPressedSelect
);
}
/**
* 视图改变事件
*
* @param listener listener
*/
public
void
setOnViewChangeListener
(
OnViewChangeListener
listener
)
{
this
.
mDelegate
.
mViewChangeListener
=
listener
;
}
public
void
setOnYearViewChangeListener
(
OnYearViewChangeListener
listener
)
{
this
.
mDelegate
.
mYearViewChangeListener
=
listener
;
}
/**
* 保持状态
*
* @return 状态
*/
@Nullable
@Override
protected
Parcelable
onSaveInstanceState
()
{
if
(
mDelegate
==
null
)
{
return
super
.
onSaveInstanceState
();
}
Bundle
bundle
=
new
Bundle
();
Parcelable
parcelable
=
super
.
onSaveInstanceState
();
bundle
.
putParcelable
(
"super"
,
parcelable
);
bundle
.
putSerializable
(
"selected_calendar"
,
mDelegate
.
mSelectedCalendar
);
bundle
.
putSerializable
(
"index_calendar"
,
mDelegate
.
mIndexCalendar
);
return
bundle
;
}
/**
* 恢复状态
*
* @param state 状态
*/
@Override
protected
void
onRestoreInstanceState
(
Parcelable
state
)
{
Bundle
bundle
=
(
Bundle
)
state
;
Parcelable
superData
=
bundle
.
getParcelable
(
"super"
);
mDelegate
.
mSelectedCalendar
=
(
Calendar
)
bundle
.
getSerializable
(
"selected_calendar"
);
mDelegate
.
mIndexCalendar
=
(
Calendar
)
bundle
.
getSerializable
(
"index_calendar"
);
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
mDelegate
.
mSelectedCalendar
,
false
);
}
if
(
mDelegate
.
mIndexCalendar
!=
null
)
{
scrollToCalendar
(
mDelegate
.
mIndexCalendar
.
getYear
(),
mDelegate
.
mIndexCalendar
.
getMonth
(),
mDelegate
.
mIndexCalendar
.
getDay
());
}
update
();
super
.
onRestoreInstanceState
(
superData
);
}
/**
* 初始化时初始化日历卡默认选择位置
*/
@Override
protected
void
onAttachedToWindow
()
{
super
.
onAttachedToWindow
();
if
(
getParent
()
!=
null
&&
getParent
()
instanceof
CalendarLayout
)
{
mParentLayout
=
(
CalendarLayout
)
getParent
();
mMonthPager
.
mParentLayout
=
mParentLayout
;
mWeekPager
.
mParentLayout
=
mParentLayout
;
mParentLayout
.
mWeekBar
=
mWeekBar
;
mParentLayout
.
setup
(
mDelegate
);
mParentLayout
.
initStatus
();
}
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
int
height
=
MeasureSpec
.
getSize
(
heightMeasureSpec
);
if
(
mDelegate
==
null
||
!
mDelegate
.
isFullScreenCalendar
())
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
return
;
}
setCalendarItemHeight
((
height
-
mDelegate
.
getWeekBarHeight
())
/
6
);
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
/**
* 标记哪些日期有事件
*
* @param mSchemeDates mSchemeDatesMap 通过自己的需求转换即可
*/
public
final
void
setSchemeDate
(
Map
<
String
,
Calendar
>
mSchemeDates
)
{
this
.
mDelegate
.
mSchemeDatesMap
=
mSchemeDates
;
this
.
mDelegate
.
updateSelectCalendarScheme
();
this
.
mYearViewPager
.
update
();
this
.
mMonthPager
.
updateScheme
();
this
.
mWeekPager
.
updateScheme
();
}
/**
* 清空日期标记
*/
public
final
void
clearSchemeDate
()
{
this
.
mDelegate
.
mSchemeDatesMap
=
null
;
this
.
mDelegate
.
clearSelectedScheme
();
mYearViewPager
.
update
();
mMonthPager
.
updateScheme
();
mWeekPager
.
updateScheme
();
}
/**
* 添加事物标记
*
* @param calendar calendar
*/
public
final
void
addSchemeDate
(
Calendar
calendar
)
{
if
(
calendar
==
null
||
!
calendar
.
isAvailable
())
{
return
;
}
if
(
mDelegate
.
mSchemeDatesMap
==
null
)
{
mDelegate
.
mSchemeDatesMap
=
new
HashMap
<>();
}
mDelegate
.
mSchemeDatesMap
.
remove
(
calendar
.
toString
());
mDelegate
.
mSchemeDatesMap
.
put
(
calendar
.
toString
(),
calendar
);
this
.
mDelegate
.
updateSelectCalendarScheme
();
this
.
mYearViewPager
.
update
();
this
.
mMonthPager
.
updateScheme
();
this
.
mWeekPager
.
updateScheme
();
}
/**
* 添加事物标记
*
* @param mSchemeDates mSchemeDates
*/
public
final
void
addSchemeDate
(
Map
<
String
,
Calendar
>
mSchemeDates
)
{
if
(
this
.
mDelegate
==
null
||
mSchemeDates
==
null
||
mSchemeDates
.
size
()
==
0
)
{
return
;
}
if
(
this
.
mDelegate
.
mSchemeDatesMap
==
null
)
{
this
.
mDelegate
.
mSchemeDatesMap
=
new
HashMap
<>();
}
this
.
mDelegate
.
addSchemes
(
mSchemeDates
);
this
.
mDelegate
.
updateSelectCalendarScheme
();
this
.
mYearViewPager
.
update
();
this
.
mMonthPager
.
updateScheme
();
this
.
mWeekPager
.
updateScheme
();
}
/**
* 移除某天的标记
* 这个API是安全的
*
* @param calendar calendar
*/
public
final
void
removeSchemeDate
(
Calendar
calendar
)
{
if
(
calendar
==
null
)
{
return
;
}
if
(
mDelegate
.
mSchemeDatesMap
==
null
||
mDelegate
.
mSchemeDatesMap
.
size
()
==
0
)
{
return
;
}
mDelegate
.
mSchemeDatesMap
.
remove
(
calendar
.
toString
());
if
(
mDelegate
.
mSelectedCalendar
.
equals
(
calendar
))
{
mDelegate
.
clearSelectedScheme
();
}
mYearViewPager
.
update
();
mMonthPager
.
updateScheme
();
mWeekPager
.
updateScheme
();
}
/**
* 设置背景色
*
* @param yearViewBackground 年份卡片的背景色
* @param weekBackground 星期栏背景色
* @param lineBg 线的颜色
*/
public
void
setBackground
(
int
yearViewBackground
,
int
weekBackground
,
int
lineBg
)
{
mWeekBar
.
setBackgroundColor
(
weekBackground
);
mYearViewPager
.
setBackgroundColor
(
yearViewBackground
);
mWeekLine
.
setBackgroundColor
(
lineBg
);
}
/**
* 设置文本颜色
*
* @param currentDayTextColor 今天字体颜色
* @param curMonthTextColor 当前月份字体颜色
* @param otherMonthColor 其它月份字体颜色
* @param curMonthLunarTextColor 当前月份农历字体颜色
* @param otherMonthLunarTextColor 其它农历字体颜色
*/
public
void
setTextColor
(
int
currentDayTextColor
,
int
curMonthTextColor
,
int
otherMonthColor
,
int
curMonthLunarTextColor
,
int
otherMonthLunarTextColor
)
{
if
(
mDelegate
==
null
||
mMonthPager
==
null
||
mWeekPager
==
null
)
{
return
;
}
mDelegate
.
setTextColor
(
currentDayTextColor
,
curMonthTextColor
,
otherMonthColor
,
curMonthLunarTextColor
,
otherMonthLunarTextColor
);
mMonthPager
.
updateStyle
();
mWeekPager
.
updateStyle
();
}
/**
* 设置选择的效果
*
* @param selectedThemeColor 选中的标记颜色
* @param selectedTextColor 选中的字体颜色
* @param selectedLunarTextColor 选中的农历字体颜色
*/
public
void
setSelectedColor
(
int
selectedThemeColor
,
int
selectedTextColor
,
int
selectedLunarTextColor
)
{
if
(
mDelegate
==
null
||
mMonthPager
==
null
||
mWeekPager
==
null
)
{
return
;
}
mDelegate
.
setSelectColor
(
selectedThemeColor
,
selectedTextColor
,
selectedLunarTextColor
);
mMonthPager
.
updateStyle
();
mWeekPager
.
updateStyle
();
}
/**
* 定制颜色
*
* @param selectedThemeColor 选中的标记颜色
* @param schemeColor 标记背景色
*/
public
void
setThemeColor
(
int
selectedThemeColor
,
int
schemeColor
)
{
if
(
mDelegate
==
null
||
mMonthPager
==
null
||
mWeekPager
==
null
)
{
return
;
}
mDelegate
.
setThemeColor
(
selectedThemeColor
,
schemeColor
);
mMonthPager
.
updateStyle
();
mWeekPager
.
updateStyle
();
}
/**
* 设置标记的色
*
* @param schemeLunarTextColor 标记农历颜色
* @param schemeColor 标记背景色
* @param schemeTextColor 标记字体颜色
*/
public
void
setSchemeColor
(
int
schemeColor
,
int
schemeTextColor
,
int
schemeLunarTextColor
)
{
if
(
mDelegate
==
null
||
mMonthPager
==
null
||
mWeekPager
==
null
)
{
return
;
}
mDelegate
.
setSchemeColor
(
schemeColor
,
schemeTextColor
,
schemeLunarTextColor
);
mMonthPager
.
updateStyle
();
mWeekPager
.
updateStyle
();
}
/**
* 设置年视图的颜色
*
* @param yearViewMonthTextColor 年视图月份颜色
* @param yearViewDayTextColor 年视图天的颜色
* @param yarViewSchemeTextColor 年视图标记颜色
*/
public
void
setYearViewTextColor
(
int
yearViewMonthTextColor
,
int
yearViewDayTextColor
,
int
yarViewSchemeTextColor
)
{
if
(
mDelegate
==
null
||
mYearViewPager
==
null
)
{
return
;
}
mDelegate
.
setYearViewTextColor
(
yearViewMonthTextColor
,
yearViewDayTextColor
,
yarViewSchemeTextColor
);
mYearViewPager
.
updateStyle
();
}
/**
* 设置星期栏的背景和字体颜色
*
* @param weekBackground 背景色
* @param weekTextColor 字体颜色
*/
public
void
setWeeColor
(
int
weekBackground
,
int
weekTextColor
)
{
if
(
mWeekBar
==
null
)
{
return
;
}
mWeekBar
.
setBackgroundColor
(
weekBackground
);
mWeekBar
.
setTextColor
(
weekTextColor
);
}
public
void
setCalendarPadding
(
int
mCalendarPadding
)
{
if
(
mDelegate
==
null
)
{
return
;
}
mDelegate
.
setCalendarPadding
(
mCalendarPadding
);
update
();
}
public
void
setCalendarPaddingLeft
(
int
mCalendarPaddingLeft
)
{
if
(
mDelegate
==
null
)
{
return
;
}
mDelegate
.
setCalendarPaddingLeft
(
mCalendarPaddingLeft
);
update
();
}
public
void
setCalendarPaddingRight
(
int
mCalendarPaddingRight
)
{
if
(
mDelegate
==
null
)
{
return
;
}
mDelegate
.
setCalendarPaddingRight
(
mCalendarPaddingRight
);
update
();
}
/**
* 默认选择模式
*/
public
final
void
setSelectDefaultMode
()
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
return
;
}
mDelegate
.
mSelectedCalendar
=
mDelegate
.
mIndexCalendar
;
mDelegate
.
setSelectMode
(
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
);
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
(),
false
);
mMonthPager
.
updateDefaultSelect
();
mWeekPager
.
updateDefaultSelect
();
}
/**
* 范围模式
*/
public
void
setSelectRangeMode
()
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_RANGE
)
{
return
;
}
mDelegate
.
setSelectMode
(
CalendarViewDelegate
.
SELECT_MODE_RANGE
);
clearSelectRange
();
}
/**
* 多选模式
*/
public
void
setSelectMultiMode
()
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_MULTI
)
{
return
;
}
mDelegate
.
setSelectMode
(
CalendarViewDelegate
.
SELECT_MODE_MULTI
);
clearMultiSelect
();
}
/**
* 单选模式
*/
public
void
setSelectSingleMode
()
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_SINGLE
)
{
return
;
}
mDelegate
.
setSelectMode
(
CalendarViewDelegate
.
SELECT_MODE_SINGLE
);
mWeekPager
.
updateSelected
();
mMonthPager
.
updateSelected
();
}
/**
* 设置星期日周起始
*/
public
void
setWeekStarWithSun
()
{
setWeekStart
(
CalendarViewDelegate
.
WEEK_START_WITH_SUN
);
}
/**
* 设置星期一周起始
*/
public
void
setWeekStarWithMon
()
{
setWeekStart
(
CalendarViewDelegate
.
WEEK_START_WITH_MON
);
}
/**
* 设置星期六周起始
*/
public
void
setWeekStarWithSat
()
{
setWeekStart
(
CalendarViewDelegate
.
WEEK_START_WITH_SAT
);
}
/**
* 设置周起始
* CalendarViewDelegate.WEEK_START_WITH_SUN
* CalendarViewDelegate.WEEK_START_WITH_MON
* CalendarViewDelegate.WEEK_START_WITH_SAT
*
* @param weekStart 周起始
*/
private
void
setWeekStart
(
int
weekStart
)
{
if
(
weekStart
!=
CalendarViewDelegate
.
WEEK_START_WITH_SUN
&&
weekStart
!=
CalendarViewDelegate
.
WEEK_START_WITH_MON
&&
weekStart
!=
CalendarViewDelegate
.
WEEK_START_WITH_SAT
)
return
;
if
(
weekStart
==
mDelegate
.
getWeekStart
())
return
;
mDelegate
.
setWeekStart
(
weekStart
);
mWeekBar
.
onWeekStartChange
(
weekStart
);
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
weekStart
,
false
);
mWeekPager
.
updateWeekStart
();
mMonthPager
.
updateWeekStart
();
mYearViewPager
.
updateWeekStart
();
}
/**
* 是否是单选模式
*
* @return isSingleSelectMode
*/
public
boolean
isSingleSelectMode
()
{
return
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_SINGLE
;
}
/**
* 设置显示模式为全部
*/
public
void
setAllMode
()
{
setShowMode
(
CalendarViewDelegate
.
MODE_ALL_MONTH
);
}
/**
* 设置显示模式为仅当前月份
*/
public
void
setOnlyCurrentMode
()
{
setShowMode
(
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
);
}
/**
* 设置显示模式为填充
*/
public
void
setFixMode
()
{
setShowMode
(
CalendarViewDelegate
.
MODE_FIT_MONTH
);
}
/**
* 设置显示模式
* CalendarViewDelegate.MODE_ALL_MONTH
* CalendarViewDelegate.MODE_ONLY_CURRENT_MONTH
* CalendarViewDelegate.MODE_FIT_MONTH
*
* @param mode 月视图显示模式
*/
private
void
setShowMode
(
int
mode
)
{
if
(
mode
!=
CalendarViewDelegate
.
MODE_ALL_MONTH
&&
mode
!=
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
&&
mode
!=
CalendarViewDelegate
.
MODE_FIT_MONTH
)
return
;
if
(
mDelegate
.
getMonthViewShowMode
()
==
mode
)
return
;
mDelegate
.
setMonthViewShowMode
(
mode
);
mWeekPager
.
updateShowMode
();
mMonthPager
.
updateShowMode
();
mWeekPager
.
notifyDataSetChanged
();
}
/**
* 更新界面,
* 重新设置颜色等都需要调用该方法
*/
public
final
void
update
()
{
mWeekBar
.
onWeekStartChange
(
mDelegate
.
getWeekStart
());
mYearViewPager
.
update
();
mMonthPager
.
updateScheme
();
mWeekPager
.
updateScheme
();
}
/**
* 更新周视图
*/
public
void
updateWeekBar
()
{
mWeekBar
.
onWeekStartChange
(
mDelegate
.
getWeekStart
());
}
/**
* 更新当前日期
*/
public
final
void
updateCurrentDate
()
{
if
(
mDelegate
==
null
||
mMonthPager
==
null
||
mWeekPager
==
null
)
{
return
;
}
java
.
util
.
Calendar
calendar
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
calendar
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
int
day
=
calendar
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
);
if
(
getCurDay
()
==
day
)
{
return
;
}
mDelegate
.
updateCurrentDay
();
mMonthPager
.
updateCurrentDate
();
mWeekPager
.
updateCurrentDate
();
}
/**
* 获取当前周数据
*
* @return 获取当前周数据
*/
public
List
<
Calendar
>
getCurrentWeekCalendars
()
{
return
mWeekPager
.
getCurrentWeekCalendars
();
}
/**
* 获取当前月份日期
*
* @return return
*/
public
List
<
Calendar
>
getCurrentMonthCalendars
()
{
return
mMonthPager
.
getCurrentMonthCalendars
();
}
/**
* 获取选择的日期
*
* @return 获取选择的日期
*/
public
Calendar
getSelectedCalendar
()
{
return
mDelegate
.
mSelectedCalendar
;
}
/**
* 获得最小范围日期
*
* @return 最小范围日期
*/
public
Calendar
getMinRangeCalendar
()
{
return
mDelegate
.
getMinRangeCalendar
();
}
/**
* 获得最大范围日期
*
* @return 最大范围日期
*/
public
Calendar
getMaxRangeCalendar
()
{
return
mDelegate
.
getMaxRangeCalendar
();
}
/**
* MonthViewPager
*
* @return 获得月视图
*/
public
MonthViewPager
getMonthViewPager
()
{
return
mMonthPager
;
}
/**
* 获得周视图
*
* @return 获得周视图
*/
public
WeekViewPager
getWeekViewPager
()
{
return
mWeekPager
;
}
/**
* 是否在日期范围内
*
* @param calendar calendar
* @return 是否在日期范围内
*/
protected
final
boolean
isInRange
(
Calendar
calendar
)
{
return
mDelegate
!=
null
&&
CalendarUtil
.
isCalendarInRange
(
calendar
,
mDelegate
);
}
/**
* 年份视图切换事件,快速年份切换
*/
public
interface
OnYearChangeListener
{
void
onYearChange
(
int
year
);
}
/**
* 月份切换事件
*/
public
interface
OnMonthChangeListener
{
void
onMonthChange
(
int
year
,
int
month
);
}
/**
* 周视图切换事件
*/
public
interface
OnWeekChangeListener
{
void
onWeekChange
(
List
<
Calendar
>
weekCalendars
);
}
/**
* 内部日期选择,不暴露外部使用
* 主要是用于更新日历CalendarLayout位置
*/
interface
OnInnerDateSelectedListener
{
/**
* 月视图点击
*
* @param calendar calendar
* @param isClick 是否是点击
*/
void
onMonthDateSelected
(
Calendar
calendar
,
boolean
isClick
);
/**
* 周视图点击
*
* @param calendar calendar
* @param isClick 是否是点击
*/
void
onWeekDateSelected
(
Calendar
calendar
,
boolean
isClick
);
}
/**
* 日历范围选择事件
*/
public
interface
OnCalendarRangeSelectListener
{
/**
* 范围选择超出范围越界
*
* @param calendar calendar
*/
void
onCalendarSelectOutOfRange
(
Calendar
calendar
);
/**
* 选择范围超出范围
*
* @param calendar calendar
* @param isOutOfMinRange 是否小于最小范围,否则为最大范围
*/
void
onSelectOutOfRange
(
Calendar
calendar
,
boolean
isOutOfMinRange
);
/**
* 日期选择事件
*
* @param calendar calendar
* @param isEnd 是否结束
*/
void
onCalendarRangeSelect
(
Calendar
calendar
,
boolean
isEnd
);
}
/**
* 日历多选事件
*/
public
interface
OnCalendarMultiSelectListener
{
/**
* 多选超出范围越界
*
* @param calendar calendar
*/
void
onCalendarMultiSelectOutOfRange
(
Calendar
calendar
);
/**
* 多选超出大小
*
* @param maxSize 最大大小
* @param calendar calendar
*/
void
onMultiSelectOutOfSize
(
Calendar
calendar
,
int
maxSize
);
/**
* 多选事件
*
* @param calendar calendar
* @param curSize curSize
* @param maxSize maxSize
*/
void
onCalendarMultiSelect
(
Calendar
calendar
,
int
curSize
,
int
maxSize
);
}
/**
* 日历选择事件
*/
public
interface
OnCalendarSelectListener
{
/**
* 超出范围越界
*
* @param calendar calendar
*/
void
onCalendarOutOfRange
(
Calendar
calendar
);
/**
* 日期选择事件
*
* @param calendar calendar
* @param isClick isClick
*/
void
onCalendarSelect
(
Calendar
calendar
,
boolean
isClick
);
}
public
interface
OnCalendarLongClickListener
{
/**
* 超出范围越界
*
* @param calendar calendar
*/
void
onCalendarLongClickOutOfRange
(
Calendar
calendar
);
/**
* 日期长按事件
*
* @param calendar calendar
*/
void
onCalendarLongClick
(
Calendar
calendar
);
}
/**
* 视图改变事件
*/
public
interface
OnViewChangeListener
{
/**
* 视图改变事件
*
* @param isMonthView isMonthView是否是月视图
*/
void
onViewChange
(
boolean
isMonthView
);
}
/**
* 年视图改变事件
*/
public
interface
OnYearViewChangeListener
{
/**
* 年视图变化
*
* @param isClose 是否关闭
*/
void
onYearViewChange
(
boolean
isClose
);
}
/**
* 拦截日期是否可用事件
*/
public
interface
OnCalendarInterceptListener
{
boolean
onCalendarIntercept
(
Calendar
calendar
);
void
onCalendarInterceptClick
(
Calendar
calendar
,
boolean
isClick
);
}
/**
* 点击Padding位置事件
*/
public
interface
OnClickCalendarPaddingListener
{
/**
* 点击Padding位置的事件
*
* @param x x坐标
* @param y y坐标
* @param isMonthView 是否是月视图,不是则为周视图
* @param adjacentCalendar 相邻的日历日期
* @param obj 此处的对象,自行设置
*/
void
onClickCalendarPadding
(
float
x
,
float
y
,
boolean
isMonthView
,
Calendar
adjacentCalendar
,
Object
obj
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CalendarViewDelegate.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.graphics.Color
;
import
android.support.annotation.Nullable
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
com.sobot.widget.R
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TimeZone
;
/**
* Google规范化的属性委托,
* 代码量多,但是不影响阅读性
*/
final
class
CalendarViewDelegate
{
private
String
zone
;
/**
* 周起始:周日
*/
static
final
int
WEEK_START_WITH_SUN
=
1
;
/**
* 周起始:周一
*/
static
final
int
WEEK_START_WITH_MON
=
2
;
/**
* 周起始:周六
*/
static
final
int
WEEK_START_WITH_SAT
=
7
;
/**
* 默认选择日期1号first_day_of_month
*/
static
final
int
FIRST_DAY_OF_MONTH
=
0
;
/**
* 跟随上个月last_select_day
*/
static
final
int
LAST_MONTH_VIEW_SELECT_DAY
=
1
;
/**
* 跟随上个月last_select_day_ignore_current忽视今天
*/
static
final
int
LAST_MONTH_VIEW_SELECT_DAY_IGNORE_CURRENT
=
2
;
private
int
mDefaultCalendarSelectDay
;
/**
* 周起始
*/
private
int
mWeekStart
;
/**
* 全部显示
*/
static
final
int
MODE_ALL_MONTH
=
0
;
/**
* 仅显示当前月份
*/
static
final
int
MODE_ONLY_CURRENT_MONTH
=
1
;
/**
* 自适应显示,不会多出一行,但是会自动填充
*/
static
final
int
MODE_FIT_MONTH
=
2
;
/**
* 月份显示模式
*/
private
int
mMonthViewShowMode
;
/**
* 默认选择模式
*/
static
final
int
SELECT_MODE_DEFAULT
=
0
;
/**
* 单选模式
*/
static
final
int
SELECT_MODE_SINGLE
=
1
;
/**
* 范围选择模式
*/
static
final
int
SELECT_MODE_RANGE
=
2
;
/**
* 多选模式
*/
static
final
int
SELECT_MODE_MULTI
=
3
;
/**
* 选择模式
*/
private
int
mSelectMode
;
/**
* 支持转换的最小农历年份
*/
static
final
int
MIN_YEAR
=
1900
;
/**
* 支持转换的最大农历年份
*/
private
static
final
int
MAX_YEAR
=
2099
;
/**
* 各种字体颜色,看名字知道对应的地方
*/
private
int
mCurDayTextColor
,
mCurDayLunarTextColor
,
mWeekTextColor
,
mSchemeTextColor
,
mSchemeLunarTextColor
,
mOtherMonthTextColor
,
mCurrentMonthTextColor
,
mSelectedTextColor
,
mSelectedLunarTextColor
,
mCurMonthLunarTextColor
,
mOtherMonthLunarTextColor
;
private
boolean
preventLongPressedSelected
;
/**
* 年视图一些padding
*/
private
int
mYearViewPadding
,
mYearViewPaddingLeft
,
mYearViewPaddingRight
;
/**
* 年视图一些padding
*/
private
int
mYearViewMonthPaddingLeft
,
mYearViewMonthPaddingRight
,
mYearViewMonthPaddingTop
,
mYearViewMonthPaddingBottom
;
/**
* 日历内部左右padding
*/
private
int
mCalendarPadding
;
/**
* 日历内部左padding
*/
private
int
mCalendarPaddingLeft
;
/**
* 日历内部右padding
*/
private
int
mCalendarPaddingRight
;
/**
* 年视图字体大小
*/
private
int
mYearViewMonthTextSize
,
mYearViewDayTextSize
,
mYearViewWeekTextSize
;
/**
* 年视图月份高度和周的高度
*/
private
int
mYearViewMonthHeight
,
mYearViewWeekHeight
;
/**
* 年视图字体和标记颜色
*/
private
int
mYearViewMonthTextColor
,
mYearViewDayTextColor
,
mYearViewSchemeTextColor
,
mYearViewSelectTextColor
,
mYearViewCurDayTextColor
,
mYearViewWeekTextColor
;
/**
* 星期栏的背景、线的背景、年份背景
*/
private
int
mWeekLineBackground
,
mYearViewBackground
,
mWeekBackground
;
/**
* 星期栏Line margin
*/
private
int
mWeekLineMargin
;
/**
* 星期栏字体大小
*/
private
int
mWeekTextSize
;
/**
* 标记的主题色和选中的主题色
*/
private
int
mSchemeThemeColor
,
mSelectedThemeColor
;
/**
* 自定义的日历路径
*/
private
String
mMonthViewClassPath
;
/**
* 月视图类
*/
private
Class
<?>
mMonthViewClass
;
/**
* 自定义周视图路径
*/
private
String
mWeekViewClassPath
;
/**
* 周视图类
*/
private
Class
<?>
mWeekViewClass
;
/**
* 自定义年视图路径
*/
private
String
mYearViewClassPath
;
/**
* 周视图类
*/
private
Class
<?>
mYearViewClass
;
/**
* 自定义周栏路径
*/
private
String
mWeekBarClassPath
;
/**
* 自定义周栏
*/
private
Class
<?>
mWeekBarClass
;
/**
* 年月视图是否打开
*/
boolean
isShowYearSelectedLayout
;
/**
* 标记文本
*/
private
String
mSchemeText
;
/**
* 最小年份和最大年份
*/
private
int
mMinYear
,
mMaxYear
;
/**
* 最小年份和最大年份对应最小月份和最大月份
* when you want set 2015-07 to 2017-08
*/
private
int
mMinYearMonth
,
mMaxYearMonth
;
/**
* 最小年份和最大年份对应最小天和最大天数
* when you want set like 2015-07-08 to 2017-08-30
*/
private
int
mMinYearDay
,
mMaxYearDay
;
/**
* 日期和农历文本大小
*/
private
int
mDayTextSize
,
mLunarTextSize
;
/**
* 日历卡的项高度
*/
private
int
mCalendarItemHeight
;
/**
* 是否是全屏日历
*/
private
boolean
isFullScreenCalendar
;
/**
* 星期栏的高度
*/
private
int
mWeekBarHeight
;
/**
* 今天的日子
*/
private
Calendar
mCurrentDate
;
private
boolean
mMonthViewScrollable
,
mWeekViewScrollable
,
mYearViewScrollable
;
/**
* 当前月份和周视图的item位置
*/
int
mCurrentMonthViewItem
;
/**
* 标记的日期,数量巨大,请使用这个
*/
Map
<
String
,
Calendar
>
mSchemeDatesMap
;
/**
* 点击Padding位置事件
*/
CalendarView
.
OnClickCalendarPaddingListener
mClickCalendarPaddingListener
;
/**
* 日期拦截事件
*/
CalendarView
.
OnCalendarInterceptListener
mCalendarInterceptListener
;
/**
* 日期选中监听
*/
CalendarView
.
OnCalendarSelectListener
mCalendarSelectListener
;
/**
* 范围选择
*/
CalendarView
.
OnCalendarRangeSelectListener
mCalendarRangeSelectListener
;
/**
* 多选选择事件
*/
CalendarView
.
OnCalendarMultiSelectListener
mCalendarMultiSelectListener
;
/**
* 外部日期长按事件
*/
CalendarView
.
OnCalendarLongClickListener
mCalendarLongClickListener
;
/**
* 内部日期切换监听,用于内部更新计算
*/
CalendarView
.
OnInnerDateSelectedListener
mInnerListener
;
/**
* 快速年份切换
*/
CalendarView
.
OnYearChangeListener
mYearChangeListener
;
/**
* 月份切换事件
*/
CalendarView
.
OnMonthChangeListener
mMonthChangeListener
;
/**
* 周视图改变事件
*/
CalendarView
.
OnWeekChangeListener
mWeekChangeListener
;
/**
* 视图改变事件
*/
CalendarView
.
OnViewChangeListener
mViewChangeListener
;
/**
* 年视图改变事件
*/
CalendarView
.
OnYearViewChangeListener
mYearViewChangeListener
;
/**
* 保存选中的日期
*/
Calendar
mSelectedCalendar
;
/**
* 保存标记位置
*/
Calendar
mIndexCalendar
;
/**
* 多选日历
*/
Map
<
String
,
Calendar
>
mSelectedCalendars
=
new
HashMap
<>();
private
int
mMaxMultiSelectSize
;
/**
* 选择范围日历
*/
Calendar
mSelectedStartRangeCalendar
,
mSelectedEndRangeCalendar
;
private
int
mMinSelectRange
,
mMaxSelectRange
;
CalendarViewDelegate
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
TypedArray
array
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
Sobot_CalendarView
);
LunarCalendar
.
init
(
context
);
mCalendarPadding
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_calendar_padding
,
0
);
mCalendarPaddingLeft
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_calendar_padding_left
,
0
);
mCalendarPaddingRight
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_calendar_padding_right
,
0
);
if
(
mCalendarPadding
!=
0
)
{
mCalendarPaddingLeft
=
mCalendarPadding
;
mCalendarPaddingRight
=
mCalendarPadding
;
}
mSchemeTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_scheme_text_color
,
0xFFFFFFFF
);
mSchemeLunarTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_scheme_lunar_text_color
,
0xFFe1e1e1
);
mSchemeThemeColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_scheme_theme_color
,
0x50CFCFCF
);
mMonthViewClassPath
=
array
.
getString
(
R
.
styleable
.
Sobot_CalendarView_month_view
);
mYearViewClassPath
=
array
.
getString
(
R
.
styleable
.
Sobot_CalendarView_year_view
);
mWeekViewClassPath
=
array
.
getString
(
R
.
styleable
.
Sobot_CalendarView_week_view
);
mWeekBarClassPath
=
array
.
getString
(
R
.
styleable
.
Sobot_CalendarView_week_bar_view
);
mWeekTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_week_text_size
,
CalendarUtil
.
dipToPx
(
context
,
12
));
mWeekBarHeight
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_week_bar_height
,
CalendarUtil
.
dipToPx
(
context
,
40
));
mWeekLineMargin
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_week_line_margin
,
CalendarUtil
.
dipToPx
(
context
,
0
));
mSchemeText
=
array
.
getString
(
R
.
styleable
.
Sobot_CalendarView_scheme_text
);
if
(
TextUtils
.
isEmpty
(
mSchemeText
))
{
mSchemeText
=
"记"
;
}
mMonthViewScrollable
=
array
.
getBoolean
(
R
.
styleable
.
Sobot_CalendarView_month_view_scrollable
,
true
);
mWeekViewScrollable
=
array
.
getBoolean
(
R
.
styleable
.
Sobot_CalendarView_week_view_scrollable
,
true
);
mYearViewScrollable
=
array
.
getBoolean
(
R
.
styleable
.
Sobot_CalendarView_year_view_scrollable
,
true
);
mDefaultCalendarSelectDay
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_month_view_auto_select_day
,
FIRST_DAY_OF_MONTH
);
mMonthViewShowMode
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_month_view_show_mode
,
MODE_ALL_MONTH
);
mWeekStart
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_week_start_with
,
WEEK_START_WITH_SUN
);
mSelectMode
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_select_mode
,
SELECT_MODE_DEFAULT
);
mMaxMultiSelectSize
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_max_multi_select_size
,
Integer
.
MAX_VALUE
);
mMinSelectRange
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_min_select_range
,
-
1
);
mMaxSelectRange
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_max_select_range
,
-
1
);
setSelectRange
(
mMinSelectRange
,
mMaxSelectRange
);
mWeekBackground
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_week_background
,
Color
.
WHITE
);
mWeekLineBackground
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_week_line_background
,
Color
.
TRANSPARENT
);
mYearViewBackground
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_background
,
Color
.
WHITE
);
mWeekTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_week_text_color
,
0xFF333333
);
mCurDayTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_current_day_text_color
,
Color
.
RED
);
mCurDayLunarTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_current_day_lunar_text_color
,
Color
.
RED
);
mSelectedThemeColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_selected_theme_color
,
0x50CFCFCF
);
mSelectedTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_selected_text_color
,
0xFF111111
);
mSelectedLunarTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_selected_lunar_text_color
,
0xFF111111
);
mCurrentMonthTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_current_month_text_color
,
0xFF111111
);
mOtherMonthTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_other_month_text_color
,
0xFFe1e1e1
);
mCurMonthLunarTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_current_month_lunar_text_color
,
0xffe1e1e1
);
mOtherMonthLunarTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_other_month_lunar_text_color
,
0xffe1e1e1
);
mMinYear
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_min_year
,
1971
);
mMaxYear
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_max_year
,
2055
);
mMinYearMonth
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_min_year_month
,
1
);
mMaxYearMonth
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_max_year_month
,
12
);
mMinYearDay
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_min_year_day
,
1
);
mMaxYearDay
=
array
.
getInt
(
R
.
styleable
.
Sobot_CalendarView_max_year_day
,
-
1
);
mDayTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_day_text_size
,
CalendarUtil
.
dipToPx
(
context
,
16
));
mLunarTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_lunar_text_size
,
CalendarUtil
.
dipToPx
(
context
,
10
));
mCalendarItemHeight
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_calendar_height
,
CalendarUtil
.
dipToPx
(
context
,
56
));
isFullScreenCalendar
=
array
.
getBoolean
(
R
.
styleable
.
Sobot_CalendarView_calendar_match_parent
,
false
);
//年视图相关
mYearViewMonthTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_text_size
,
CalendarUtil
.
dipToPx
(
context
,
18
));
mYearViewDayTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_year_view_day_text_size
,
CalendarUtil
.
dipToPx
(
context
,
7
));
mYearViewMonthTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_text_color
,
0xFF111111
);
mYearViewDayTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_day_text_color
,
0xFF111111
);
mYearViewSchemeTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_scheme_color
,
mSchemeThemeColor
);
mYearViewWeekTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_week_text_color
,
0xFF333333
);
mYearViewCurDayTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_current_day_text_color
,
mCurDayTextColor
);
mYearViewSelectTextColor
=
array
.
getColor
(
R
.
styleable
.
Sobot_CalendarView_year_view_select_text_color
,
0xFF333333
);
mYearViewWeekTextSize
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_year_view_week_text_size
,
CalendarUtil
.
dipToPx
(
context
,
8
));
mYearViewMonthHeight
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_height
,
CalendarUtil
.
dipToPx
(
context
,
32
));
mYearViewWeekHeight
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
Sobot_CalendarView_year_view_week_height
,
CalendarUtil
.
dipToPx
(
context
,
0
));
mYearViewPadding
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_padding
,
CalendarUtil
.
dipToPx
(
context
,
12
));
mYearViewPaddingLeft
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_padding_left
,
CalendarUtil
.
dipToPx
(
context
,
12
));
mYearViewPaddingRight
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_padding_right
,
CalendarUtil
.
dipToPx
(
context
,
12
));
if
(
mYearViewPadding
!=
0
)
{
mYearViewPaddingLeft
=
mYearViewPadding
;
mYearViewPaddingRight
=
mYearViewPadding
;
}
mYearViewMonthPaddingTop
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_padding_top
,
CalendarUtil
.
dipToPx
(
context
,
4
));
mYearViewMonthPaddingBottom
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_padding_bottom
,
CalendarUtil
.
dipToPx
(
context
,
4
));
mYearViewMonthPaddingLeft
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_padding_left
,
CalendarUtil
.
dipToPx
(
context
,
4
));
mYearViewMonthPaddingRight
=
(
int
)
array
.
getDimension
(
R
.
styleable
.
Sobot_CalendarView_year_view_month_padding_right
,
CalendarUtil
.
dipToPx
(
context
,
4
));
if
(
mMinYear
<=
MIN_YEAR
)
mMinYear
=
MIN_YEAR
;
if
(
mMaxYear
>=
MAX_YEAR
)
mMaxYear
=
MAX_YEAR
;
array
.
recycle
();
init
();
}
public
void
setZone
(
String
zone
){
this
.
zone
=
zone
;
}
private
void
init
()
{
mCurrentDate
=
new
Calendar
();
Date
d
=
new
Date
();
mCurrentDate
.
setYear
(
CalendarUtil
.
getDate
(
"yyyy"
,
d
));
mCurrentDate
.
setMonth
(
CalendarUtil
.
getDate
(
"MM"
,
d
));
mCurrentDate
.
setDay
(
CalendarUtil
.
getDate
(
"dd"
,
d
));
mCurrentDate
.
setCurrentDay
(
true
);
LunarCalendar
.
setupLunarCalendar
(
mCurrentDate
);
setRange
(
mMinYear
,
mMinYearMonth
,
mMaxYear
,
mMaxYearMonth
);
try
{
mWeekBarClass
=
TextUtils
.
isEmpty
(
mWeekBarClassPath
)
?
mWeekBarClass
=
WeekBar
.
class
:
Class
.
forName
(
mWeekBarClassPath
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
try
{
mYearViewClass
=
TextUtils
.
isEmpty
(
mYearViewClassPath
)
?
mYearViewClass
=
DefaultYearView
.
class
:
Class
.
forName
(
mYearViewClassPath
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
try
{
mMonthViewClass
=
TextUtils
.
isEmpty
(
mMonthViewClassPath
)
?
DefaultMonthView
.
class
:
Class
.
forName
(
mMonthViewClassPath
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
try
{
mWeekViewClass
=
TextUtils
.
isEmpty
(
mWeekViewClassPath
)
?
DefaultWeekView
.
class
:
Class
.
forName
(
mWeekViewClassPath
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
private
void
setRange
(
int
minYear
,
int
minYearMonth
,
int
maxYear
,
int
maxYearMonth
)
{
this
.
mMinYear
=
minYear
;
this
.
mMinYearMonth
=
minYearMonth
;
this
.
mMaxYear
=
maxYear
;
this
.
mMaxYearMonth
=
maxYearMonth
;
if
(
this
.
mMaxYear
<
mCurrentDate
.
getYear
())
{
this
.
mMaxYear
=
mCurrentDate
.
getYear
();
}
if
(
this
.
mMaxYearDay
==
-
1
)
{
this
.
mMaxYearDay
=
CalendarUtil
.
getMonthDaysCount
(
this
.
mMaxYear
,
mMaxYearMonth
);
}
int
y
=
mCurrentDate
.
getYear
()
-
this
.
mMinYear
;
mCurrentMonthViewItem
=
12
*
y
+
mCurrentDate
.
getMonth
()
-
this
.
mMinYearMonth
;
}
void
setRange
(
int
minYear
,
int
minYearMonth
,
int
minYearDay
,
int
maxYear
,
int
maxYearMonth
,
int
maxYearDay
)
{
this
.
mMinYear
=
minYear
;
this
.
mMinYearMonth
=
minYearMonth
;
this
.
mMinYearDay
=
minYearDay
;
this
.
mMaxYear
=
maxYear
;
this
.
mMaxYearMonth
=
maxYearMonth
;
this
.
mMaxYearDay
=
maxYearDay
;
// if (this.mMaxYear < mCurrentDate.getYear()) {
// this.mMaxYear = mCurrentDate.getYear();
// }
if
(
this
.
mMaxYearDay
==
-
1
)
{
this
.
mMaxYearDay
=
CalendarUtil
.
getMonthDaysCount
(
this
.
mMaxYear
,
mMaxYearMonth
);
}
int
y
=
mCurrentDate
.
getYear
()
-
this
.
mMinYear
;
mCurrentMonthViewItem
=
12
*
y
+
mCurrentDate
.
getMonth
()
-
this
.
mMinYearMonth
;
}
String
getSchemeText
()
{
return
mSchemeText
;
}
int
getCurDayTextColor
()
{
return
mCurDayTextColor
;
}
int
getCurDayLunarTextColor
()
{
return
mCurDayLunarTextColor
;
}
int
getWeekTextColor
()
{
return
mWeekTextColor
;
}
int
getSchemeTextColor
()
{
return
mSchemeTextColor
;
}
int
getSchemeLunarTextColor
()
{
return
mSchemeLunarTextColor
;
}
int
getOtherMonthTextColor
()
{
return
mOtherMonthTextColor
;
}
int
getCurrentMonthTextColor
()
{
return
mCurrentMonthTextColor
;
}
int
getSelectedTextColor
()
{
return
mSelectedTextColor
;
}
int
getSelectedLunarTextColor
()
{
return
mSelectedLunarTextColor
;
}
int
getCurrentMonthLunarTextColor
()
{
return
mCurMonthLunarTextColor
;
}
int
getOtherMonthLunarTextColor
()
{
return
mOtherMonthLunarTextColor
;
}
int
getSchemeThemeColor
()
{
return
mSchemeThemeColor
;
}
int
getSelectedThemeColor
()
{
return
mSelectedThemeColor
;
}
int
getWeekBackground
()
{
return
mWeekBackground
;
}
int
getYearViewBackground
()
{
return
mYearViewBackground
;
}
int
getWeekLineBackground
()
{
return
mWeekLineBackground
;
}
int
getWeekLineMargin
()
{
return
mWeekLineMargin
;
}
Class
<?>
getMonthViewClass
()
{
return
mMonthViewClass
;
}
Class
<?>
getWeekViewClass
()
{
return
mWeekViewClass
;
}
Class
<?>
getWeekBarClass
()
{
return
mWeekBarClass
;
}
Class
<?>
getYearViewClass
()
{
return
mYearViewClass
;
}
String
getYearViewClassPath
()
{
return
mYearViewClassPath
;
}
int
getWeekBarHeight
()
{
return
mWeekBarHeight
;
}
int
getMinYear
()
{
return
mMinYear
;
}
int
getMaxYear
()
{
return
mMaxYear
;
}
int
getDayTextSize
()
{
return
mDayTextSize
;
}
int
getLunarTextSize
()
{
return
mLunarTextSize
;
}
int
getCalendarItemHeight
()
{
return
mCalendarItemHeight
;
}
void
setCalendarItemHeight
(
int
height
)
{
mCalendarItemHeight
=
height
;
}
int
getMinYearMonth
()
{
return
mMinYearMonth
;
}
int
getMaxYearMonth
()
{
return
mMaxYearMonth
;
}
int
getYearViewMonthTextSize
()
{
return
mYearViewMonthTextSize
;
}
int
getYearViewMonthTextColor
()
{
return
mYearViewMonthTextColor
;
}
int
getYearViewWeekTextSize
()
{
return
mYearViewWeekTextSize
;
}
int
getYearViewWeekTextColor
()
{
return
mYearViewWeekTextColor
;
}
int
getYearViewSelectTextColor
()
{
return
mYearViewSelectTextColor
;
}
int
getYearViewCurDayTextColor
()
{
return
mYearViewCurDayTextColor
;
}
@SuppressWarnings
(
"unused"
)
int
getYearViewPadding
()
{
return
mYearViewPadding
;
}
int
getYearViewPaddingLeft
()
{
return
mYearViewPaddingLeft
;
}
int
getYearViewPaddingRight
()
{
return
mYearViewPaddingRight
;
}
int
getYearViewMonthPaddingLeft
()
{
return
mYearViewMonthPaddingLeft
;
}
int
getYearViewMonthPaddingRight
()
{
return
mYearViewMonthPaddingRight
;
}
int
getYearViewMonthPaddingTop
()
{
return
mYearViewMonthPaddingTop
;
}
int
getYearViewMonthPaddingBottom
()
{
return
mYearViewMonthPaddingBottom
;
}
int
getYearViewWeekHeight
()
{
return
mYearViewWeekHeight
;
}
int
getYearViewMonthHeight
()
{
return
mYearViewMonthHeight
;
}
int
getYearViewDayTextColor
()
{
return
mYearViewDayTextColor
;
}
int
getYearViewDayTextSize
()
{
return
mYearViewDayTextSize
;
}
int
getYearViewSchemeTextColor
()
{
return
mYearViewSchemeTextColor
;
}
int
getMonthViewShowMode
()
{
return
mMonthViewShowMode
;
}
void
setMonthViewShowMode
(
int
monthViewShowMode
)
{
this
.
mMonthViewShowMode
=
monthViewShowMode
;
}
void
setTextColor
(
int
curDayTextColor
,
int
curMonthTextColor
,
int
otherMonthTextColor
,
int
curMonthLunarTextColor
,
int
otherMonthLunarTextColor
)
{
mCurDayTextColor
=
curDayTextColor
;
mOtherMonthTextColor
=
otherMonthTextColor
;
mCurrentMonthTextColor
=
curMonthTextColor
;
mCurMonthLunarTextColor
=
curMonthLunarTextColor
;
mOtherMonthLunarTextColor
=
otherMonthLunarTextColor
;
}
void
setSchemeColor
(
int
schemeColor
,
int
schemeTextColor
,
int
schemeLunarTextColor
)
{
this
.
mSchemeThemeColor
=
schemeColor
;
this
.
mSchemeTextColor
=
schemeTextColor
;
this
.
mSchemeLunarTextColor
=
schemeLunarTextColor
;
}
void
setYearViewTextColor
(
int
yearViewMonthTextColor
,
int
yearViewDayTextColor
,
int
yarViewSchemeTextColor
)
{
this
.
mYearViewMonthTextColor
=
yearViewMonthTextColor
;
this
.
mYearViewDayTextColor
=
yearViewDayTextColor
;
this
.
mYearViewSchemeTextColor
=
yarViewSchemeTextColor
;
}
void
setSelectColor
(
int
selectedColor
,
int
selectedTextColor
,
int
selectedLunarTextColor
)
{
this
.
mSelectedThemeColor
=
selectedColor
;
this
.
mSelectedTextColor
=
selectedTextColor
;
this
.
mSelectedLunarTextColor
=
selectedLunarTextColor
;
}
void
setThemeColor
(
int
selectedThemeColor
,
int
schemeColor
)
{
this
.
mSelectedThemeColor
=
selectedThemeColor
;
this
.
mSchemeThemeColor
=
schemeColor
;
}
boolean
isMonthViewScrollable
()
{
return
mMonthViewScrollable
;
}
boolean
isWeekViewScrollable
()
{
return
mWeekViewScrollable
;
}
boolean
isYearViewScrollable
()
{
return
mYearViewScrollable
;
}
void
setMonthViewScrollable
(
boolean
monthViewScrollable
)
{
this
.
mMonthViewScrollable
=
monthViewScrollable
;
}
void
setWeekViewScrollable
(
boolean
weekViewScrollable
)
{
this
.
mWeekViewScrollable
=
weekViewScrollable
;
}
void
setYearViewScrollable
(
boolean
yearViewScrollable
)
{
this
.
mYearViewScrollable
=
yearViewScrollable
;
}
int
getWeekStart
()
{
return
mWeekStart
;
}
void
setWeekStart
(
int
mWeekStart
)
{
this
.
mWeekStart
=
mWeekStart
;
}
void
setDefaultCalendarSelectDay
(
int
defaultCalendarSelect
)
{
this
.
mDefaultCalendarSelectDay
=
defaultCalendarSelect
;
}
int
getDefaultCalendarSelectDay
()
{
return
mDefaultCalendarSelectDay
;
}
int
getWeekTextSize
()
{
return
mWeekTextSize
;
}
/**
* 选择模式
*
* @return 选择模式
*/
int
getSelectMode
()
{
return
mSelectMode
;
}
/**
* 设置选择模式
*
* @param mSelectMode mSelectMode
*/
void
setSelectMode
(
int
mSelectMode
)
{
this
.
mSelectMode
=
mSelectMode
;
}
int
getMinSelectRange
()
{
return
mMinSelectRange
;
}
int
getMaxSelectRange
()
{
return
mMaxSelectRange
;
}
int
getMaxMultiSelectSize
()
{
return
mMaxMultiSelectSize
;
}
void
setMaxMultiSelectSize
(
int
maxMultiSelectSize
)
{
this
.
mMaxMultiSelectSize
=
maxMultiSelectSize
;
}
final
void
setSelectRange
(
int
minRange
,
int
maxRange
)
{
if
(
minRange
>
maxRange
&&
maxRange
>
0
)
{
mMaxSelectRange
=
minRange
;
mMinSelectRange
=
minRange
;
return
;
}
if
(
minRange
<=
0
)
{
mMinSelectRange
=
-
1
;
}
else
{
mMinSelectRange
=
minRange
;
}
if
(
maxRange
<=
0
)
{
mMaxSelectRange
=
-
1
;
}
else
{
mMaxSelectRange
=
maxRange
;
}
}
Calendar
getCurrentDay
()
{
return
mCurrentDate
;
}
void
updateCurrentDay
()
{
Date
d
=
new
Date
();
mCurrentDate
.
setYear
(
CalendarUtil
.
getDate
(
"yyyy"
,
d
));
mCurrentDate
.
setMonth
(
CalendarUtil
.
getDate
(
"MM"
,
d
));
mCurrentDate
.
setDay
(
CalendarUtil
.
getDate
(
"dd"
,
d
));
LunarCalendar
.
setupLunarCalendar
(
mCurrentDate
);
}
@SuppressWarnings
(
"unused"
)
int
getCalendarPadding
()
{
return
mCalendarPadding
;
}
void
setCalendarPadding
(
int
mCalendarPadding
)
{
this
.
mCalendarPadding
=
mCalendarPadding
;
mCalendarPaddingLeft
=
mCalendarPadding
;
mCalendarPaddingRight
=
mCalendarPadding
;
}
int
getCalendarPaddingLeft
()
{
return
mCalendarPaddingLeft
;
}
void
setCalendarPaddingLeft
(
int
mCalendarPaddingLeft
)
{
this
.
mCalendarPaddingLeft
=
mCalendarPaddingLeft
;
}
int
getCalendarPaddingRight
()
{
return
mCalendarPaddingRight
;
}
void
setCalendarPaddingRight
(
int
mCalendarPaddingRight
)
{
this
.
mCalendarPaddingRight
=
mCalendarPaddingRight
;
}
void
setPreventLongPressedSelected
(
boolean
preventLongPressedSelected
)
{
this
.
preventLongPressedSelected
=
preventLongPressedSelected
;
}
void
setMonthViewClass
(
Class
<?>
monthViewClass
)
{
this
.
mMonthViewClass
=
monthViewClass
;
}
void
setWeekBarClass
(
Class
<?>
weekBarClass
)
{
this
.
mWeekBarClass
=
weekBarClass
;
}
void
setWeekViewClass
(
Class
<?>
weekViewClass
)
{
this
.
mWeekViewClass
=
weekViewClass
;
}
boolean
isPreventLongPressedSelected
()
{
return
preventLongPressedSelected
;
}
void
clearSelectedScheme
()
{
mSelectedCalendar
.
clearScheme
();
}
int
getMinYearDay
()
{
return
mMinYearDay
;
}
int
getMaxYearDay
()
{
return
mMaxYearDay
;
}
boolean
isFullScreenCalendar
()
{
return
isFullScreenCalendar
;
}
final
void
updateSelectCalendarScheme
()
{
if
(
mSchemeDatesMap
!=
null
&&
mSchemeDatesMap
.
size
()
>
0
)
{
String
key
=
mSelectedCalendar
.
toString
();
if
(
mSchemeDatesMap
.
containsKey
(
key
))
{
Calendar
d
=
mSchemeDatesMap
.
get
(
key
);
mSelectedCalendar
.
mergeScheme
(
d
,
getSchemeText
());
}
}
else
{
clearSelectedScheme
();
}
}
final
void
updateCalendarScheme
(
Calendar
targetCalendar
)
{
if
(
targetCalendar
==
null
)
{
return
;
}
if
(
mSchemeDatesMap
==
null
||
mSchemeDatesMap
.
size
()
==
0
)
{
return
;
}
String
key
=
targetCalendar
.
toString
();
if
(
mSchemeDatesMap
.
containsKey
(
key
))
{
Calendar
d
=
mSchemeDatesMap
.
get
(
key
);
targetCalendar
.
mergeScheme
(
d
,
getSchemeText
());
}
}
Calendar
createCurrentDate
()
{
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
mCurrentDate
.
getYear
());
calendar
.
setWeek
(
mCurrentDate
.
getWeek
());
calendar
.
setMonth
(
mCurrentDate
.
getMonth
());
calendar
.
setDay
(
mCurrentDate
.
getDay
());
calendar
.
setCurrentDay
(
true
);
LunarCalendar
.
setupLunarCalendar
(
calendar
);
return
calendar
;
}
final
Calendar
getMinRangeCalendar
()
{
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
mMinYear
);
calendar
.
setMonth
(
mMinYearMonth
);
calendar
.
setDay
(
mMinYearDay
);
calendar
.
setCurrentDay
(
calendar
.
equals
(
mCurrentDate
));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
return
calendar
;
}
@SuppressWarnings
(
"unused"
)
final
Calendar
getMaxRangeCalendar
()
{
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
mMaxYear
);
calendar
.
setMonth
(
mMaxYearMonth
);
calendar
.
setDay
(
mMaxYearDay
);
calendar
.
setCurrentDay
(
calendar
.
equals
(
mCurrentDate
));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
return
calendar
;
}
/**
* 添加事件标记,来自Map
*/
final
void
addSchemesFromMap
(
List
<
Calendar
>
mItems
)
{
if
(
mSchemeDatesMap
==
null
||
mSchemeDatesMap
.
size
()
==
0
)
{
return
;
}
for
(
Calendar
a
:
mItems
)
{
if
(
mSchemeDatesMap
.
containsKey
(
a
.
toString
()))
{
Calendar
d
=
mSchemeDatesMap
.
get
(
a
.
toString
());
if
(
d
==
null
)
{
continue
;
}
a
.
setScheme
(
TextUtils
.
isEmpty
(
d
.
getScheme
())
?
getSchemeText
()
:
d
.
getScheme
());
a
.
setSchemeColor
(
d
.
getSchemeColor
());
a
.
setSchemes
(
d
.
getSchemes
());
}
else
{
a
.
setScheme
(
""
);
a
.
setSchemeColor
(
0
);
a
.
setSchemes
(
null
);
}
}
}
/**
* 添加数据
*
* @param mSchemeDates mSchemeDates
*/
final
void
addSchemes
(
Map
<
String
,
Calendar
>
mSchemeDates
)
{
if
(
mSchemeDates
==
null
||
mSchemeDates
.
size
()
==
0
)
{
return
;
}
if
(
this
.
mSchemeDatesMap
==
null
)
{
this
.
mSchemeDatesMap
=
new
HashMap
<>();
}
for
(
String
key
:
mSchemeDates
.
keySet
())
{
this
.
mSchemeDatesMap
.
remove
(
key
);
Calendar
calendar
=
mSchemeDates
.
get
(
key
);
if
(
calendar
==
null
)
{
continue
;
}
this
.
mSchemeDatesMap
.
put
(
key
,
calendar
);
}
}
/**
* 清楚选择
*/
final
void
clearSelectRange
()
{
mSelectedStartRangeCalendar
=
null
;
mSelectedEndRangeCalendar
=
null
;
}
/**
* 获得选中范围
*
* @return 选中范围
*/
final
List
<
Calendar
>
getSelectCalendarRange
()
{
if
(
mSelectMode
!=
SELECT_MODE_RANGE
)
{
return
null
;
}
List
<
Calendar
>
calendars
=
new
ArrayList
<>();
if
(
mSelectedStartRangeCalendar
==
null
||
mSelectedEndRangeCalendar
==
null
)
{
return
calendars
;
}
final
long
ONE_DAY
=
1000
*
3600
*
24
;
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
if
(!
TextUtils
.
isEmpty
(
zone
))
{
date
.
setTimeZone
(
TimeZone
.
getTimeZone
(
zone
));
}
date
.
set
(
mSelectedStartRangeCalendar
.
getYear
(),
mSelectedStartRangeCalendar
.
getMonth
()
-
1
,
mSelectedStartRangeCalendar
.
getDay
());
//
long
startTimeMills
=
date
.
getTimeInMillis
();
//获得起始时间戳
date
.
set
(
mSelectedEndRangeCalendar
.
getYear
(),
mSelectedEndRangeCalendar
.
getMonth
()
-
1
,
mSelectedEndRangeCalendar
.
getDay
());
//
long
endTimeMills
=
date
.
getTimeInMillis
();
for
(
long
start
=
startTimeMills
;
start
<=
endTimeMills
;
start
+=
ONE_DAY
)
{
date
.
setTimeInMillis
(
start
);
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
date
.
get
(
java
.
util
.
Calendar
.
YEAR
));
calendar
.
setMonth
(
date
.
get
(
java
.
util
.
Calendar
.
MONTH
)
+
1
);
calendar
.
setDay
(
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_MONTH
));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
updateCalendarScheme
(
calendar
);
if
(
mCalendarInterceptListener
!=
null
&&
mCalendarInterceptListener
.
onCalendarIntercept
(
calendar
))
{
continue
;
}
calendars
.
add
(
calendar
);
}
addSchemesFromMap
(
calendars
);
return
calendars
;
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CustomRangeMonthView.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* https://github.com/huanghaibin-dev/CalendarView
*
* 范围选择月视图
*/
public
class
CustomRangeMonthView
extends
RangeMonthView
{
private
int
mRadius
;
public
CustomRangeMonthView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onPreviewHook
()
{
mRadius
=
Math
.
min
(
mItemWidth
,
mItemHeight
)
/
5
*
2
;
mSchemePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
}
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
y
+
mItemHeight
/
2
;
if
(
isSelectedPre
)
{
if
(
isSelectedNext
)
{
canvas
.
drawRect
(
x
,
cy
-
mRadius
,
x
+
mItemWidth
,
cy
+
mRadius
,
mSelectedPaint
);
}
else
{
//最后一个,the last
canvas
.
drawRect
(
x
,
cy
-
mRadius
,
cx
,
cy
+
mRadius
,
mSelectedPaint
);
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
}
}
else
{
if
(
isSelectedNext
){
canvas
.
drawRect
(
cx
,
cy
-
mRadius
,
x
+
mItemWidth
,
cy
+
mRadius
,
mSelectedPaint
);
}
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
//
}
return
false
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
isSelected
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
y
+
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSchemePaint
);
}
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
)
{
float
baselineY
=
mTextBaseLine
+
y
;
int
cx
=
x
+
mItemWidth
/
2
;
boolean
isInRange
=
isInRange
(
calendar
);
boolean
isEnable
=
!
onCalendarIntercept
(
calendar
);
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
mSelectTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
&&
isInRange
&&
isEnable
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
&&
isInRange
&&
isEnable
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CustomRangeWeekView.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* https://github.com/huanghaibin-dev/CalendarView
*
* 范围选择周视图
*/
public
class
CustomRangeWeekView
extends
RangeWeekView
{
private
int
mRadius
;
public
CustomRangeWeekView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onPreviewHook
()
{
mRadius
=
Math
.
min
(
mItemWidth
,
mItemHeight
)
/
5
*
2
;
mSchemePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
}
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
mItemHeight
/
2
;
if
(
isSelectedPre
)
{
if
(
isSelectedNext
)
{
canvas
.
drawRect
(
x
,
cy
-
mRadius
,
x
+
mItemWidth
,
cy
+
mRadius
,
mSelectedPaint
);
}
else
{
//最后一个,the last
canvas
.
drawRect
(
x
,
cy
-
mRadius
,
cx
,
cy
+
mRadius
,
mSelectedPaint
);
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
}
}
else
{
if
(
isSelectedNext
)
{
canvas
.
drawRect
(
cx
,
cy
-
mRadius
,
x
+
mItemWidth
,
cy
+
mRadius
,
mSelectedPaint
);
}
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
}
return
false
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
isSelected
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSchemePaint
);
}
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
)
{
float
baselineY
=
mTextBaseLine
;
int
cx
=
x
+
mItemWidth
/
2
;
boolean
isInRange
=
isInRange
(
calendar
);
boolean
isEnable
=
!
onCalendarIntercept
(
calendar
);
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
mSelectTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
&&
isInRange
&&
isEnable
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
&&
isInRange
&&
isEnable
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/CustomWeekBar.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Color
;
import
android.view.LayoutInflater
;
import
android.widget.TextView
;
import
com.sobot.widget.R
;
/**
* 自定义英文栏
*/
public
class
CustomWeekBar
extends
WeekBar
{
private
int
mPreSelectedIndex
;
public
CustomWeekBar
(
Context
context
)
{
super
(
context
);
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
sobot_custom_week_bar
,
this
,
true
);
setBackgroundColor
(
Color
.
WHITE
);
}
@Override
protected
void
onDateSelected
(
Calendar
calendar
,
int
weekStart
,
boolean
isClick
)
{
getChildAt
(
mPreSelectedIndex
).
setSelected
(
false
);
int
viewIndex
=
getViewIndexByCalendar
(
calendar
,
weekStart
);
getChildAt
(
viewIndex
).
setSelected
(
true
);
mPreSelectedIndex
=
viewIndex
;
}
/**
* 当周起始发生变化,使用自定义布局需要重写这个方法,避免出问题
*
* @param weekStart 周起始
*/
@Override
protected
void
onWeekStartChange
(
int
weekStart
)
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
((
TextView
)
getChildAt
(
i
)).
setText
(
getWeekString
(
i
,
weekStart
));
}
}
/**
* 或者周文本,这个方法仅供父类使用
* @param index index
* @param weekStart weekStart
* @return 或者周文本
*/
private
String
getWeekString
(
int
index
,
int
weekStart
)
{
String
[]
weeks
=
getContext
().
getResources
().
getStringArray
(
R
.
array
.
week_string_array
);
if
(
weekStart
==
1
)
{
return
weeks
[
index
];
}
if
(
weekStart
==
2
)
{
return
weeks
[
index
==
6
?
0
:
index
+
1
];
}
return
weeks
[
index
==
0
?
6
:
index
-
1
];
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/DefaultMonthView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* 默认高仿魅族日历布局
*/
public
final
class
DefaultMonthView
extends
MonthView
{
private
Paint
mTextPaint
=
new
Paint
();
private
Paint
mSchemeBasicPaint
=
new
Paint
();
private
float
mRadio
;
private
int
mPadding
;
private
float
mSchemeBaseLine
;
public
DefaultMonthView
(
Context
context
)
{
super
(
context
);
mTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
8
));
mTextPaint
.
setColor
(
0xffFFFFFF
);
mTextPaint
.
setAntiAlias
(
true
);
mTextPaint
.
setFakeBoldText
(
true
);
mSchemeBasicPaint
.
setAntiAlias
(
true
);
mSchemeBasicPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemeBasicPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeBasicPaint
.
setColor
(
0xffed5353
);
mSchemeBasicPaint
.
setFakeBoldText
(
true
);
mRadio
=
CalendarUtil
.
dipToPx
(
getContext
(),
7
);
mPadding
=
CalendarUtil
.
dipToPx
(
getContext
(),
4
);
Paint
.
FontMetrics
metrics
=
mSchemeBasicPaint
.
getFontMetrics
();
mSchemeBaseLine
=
mRadio
-
metrics
.
descent
+
(
metrics
.
bottom
-
metrics
.
top
)
/
2
+
CalendarUtil
.
dipToPx
(
getContext
(),
1
);
}
/**
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return true 则绘制onDrawScheme,因为这里背景色不是是互斥的
*/
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
)
{
mSelectedPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
canvas
.
drawRect
(
x
+
mPadding
,
y
+
mPadding
,
x
+
mItemWidth
-
mPadding
,
y
+
mItemHeight
-
mPadding
,
mSelectedPaint
);
return
true
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
)
{
mSchemeBasicPaint
.
setColor
(
calendar
.
getSchemeColor
());
canvas
.
drawCircle
(
x
+
mItemWidth
-
mPadding
-
mRadio
/
2
,
y
+
mPadding
+
mRadio
,
mRadio
,
mSchemeBasicPaint
);
canvas
.
drawText
(
calendar
.
getScheme
(),
x
+
mItemWidth
-
mPadding
-
mRadio
/
2
-
getTextWidth
(
calendar
.
getScheme
())
/
2
,
y
+
mPadding
+
mSchemeBaseLine
,
mTextPaint
);
}
/**
* 获取字体的宽
* @param text text
* @return return
*/
private
float
getTextWidth
(
String
text
)
{
return
mTextPaint
.
measureText
(
text
);
}
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
top
=
y
-
mItemHeight
/
6
;
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
mSelectTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
y
+
mItemHeight
/
10
,
mSelectedLunarTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
y
+
mItemHeight
/
10
,
calendar
.
isCurrentDay
()
?
mCurDayLunarTextPaint
:
mSchemeLunarTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
y
+
mItemHeight
/
10
,
calendar
.
isCurrentDay
()
?
mCurDayLunarTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthLunarTextPaint
:
mOtherMonthLunarTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/DefaultWeekView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* 默认高仿魅族周视图
*/
public
final
class
DefaultWeekView
extends
WeekView
{
private
Paint
mTextPaint
=
new
Paint
();
private
Paint
mSchemeBasicPaint
=
new
Paint
();
private
float
mRadio
;
private
int
mPadding
;
private
float
mSchemeBaseLine
;
public
DefaultWeekView
(
Context
context
)
{
super
(
context
);
mTextPaint
.
setTextSize
(
CalendarUtil
.
dipToPx
(
context
,
8
));
mTextPaint
.
setColor
(
0xffffffff
);
mTextPaint
.
setAntiAlias
(
true
);
mTextPaint
.
setFakeBoldText
(
true
);
mSchemeBasicPaint
.
setAntiAlias
(
true
);
mSchemeBasicPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemeBasicPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeBasicPaint
.
setColor
(
0xffed5353
);
mSchemeBasicPaint
.
setFakeBoldText
(
true
);
mRadio
=
CalendarUtil
.
dipToPx
(
getContext
(),
7
);
mPadding
=
CalendarUtil
.
dipToPx
(
getContext
(),
4
);
Paint
.
FontMetrics
metrics
=
mSchemeBasicPaint
.
getFontMetrics
();
mSchemeBaseLine
=
mRadio
-
metrics
.
descent
+
(
metrics
.
bottom
-
metrics
.
top
)
/
2
+
CalendarUtil
.
dipToPx
(
getContext
(),
1
);
}
/**
* 如果需要点击Scheme没有效果,则return true
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return true 则绘制onDrawScheme,因为这里背景色不是是互斥的
*/
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
)
{
mSelectedPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
canvas
.
drawRect
(
x
+
mPadding
,
mPadding
,
x
+
mItemWidth
-
mPadding
,
mItemHeight
-
mPadding
,
mSelectedPaint
);
return
true
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
)
{
mSchemeBasicPaint
.
setColor
(
calendar
.
getSchemeColor
());
canvas
.
drawCircle
(
x
+
mItemWidth
-
mPadding
-
mRadio
/
2
,
mPadding
+
mRadio
,
mRadio
,
mSchemeBasicPaint
);
canvas
.
drawText
(
calendar
.
getScheme
(),
x
+
mItemWidth
-
mPadding
-
mRadio
/
2
-
getTextWidth
(
calendar
.
getScheme
())
/
2
,
mPadding
+
mSchemeBaseLine
,
mTextPaint
);
}
/**
* 获取字体的宽
* @param text text
* @return return
*/
private
float
getTextWidth
(
String
text
)
{
return
mTextPaint
.
measureText
(
text
);
}
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
top
=
-
mItemHeight
/
6
;
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
mSelectTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
mItemHeight
/
10
,
mSelectedLunarTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
mItemHeight
/
10
,
calendar
.
isCurrentDay
()
?
mCurDayLunarTextPaint
:
mSchemeLunarTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
mTextBaseLine
+
top
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
canvas
.
drawText
(
calendar
.
getLunar
(),
cx
,
mTextBaseLine
+
mItemHeight
/
10
,
calendar
.
isCurrentDay
()
?
mCurDayLunarTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthLunarTextPaint
:
mOtherMonthLunarTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/DefaultYearView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
com.sobot.widget.R
;
/**
* 默认年视图
*/
public
class
DefaultYearView
extends
YearView
{
private
int
mTextPadding
;
public
DefaultYearView
(
Context
context
)
{
super
(
context
);
mTextPadding
=
CalendarUtil
.
dipToPx
(
context
,
3
);
}
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
@Override
protected
void
onDrawMonth
(
Canvas
canvas
,
int
year
,
int
month
,
int
x
,
int
y
,
int
width
,
int
height
)
{
String
text
=
getContext
()
.
getResources
()
.
getStringArray
(
R
.
array
.
month_string_array
)[
month
-
1
];
canvas
.
drawText
(
text
,
x
+
mItemWidth
/
2
-
mTextPadding
,
y
+
mMonthTextBaseLine
,
mMonthTextPaint
);
}
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
@Override
protected
void
onDrawWeek
(
Canvas
canvas
,
int
week
,
int
x
,
int
y
,
int
width
,
int
height
)
{
String
text
=
getContext
().
getResources
().
getStringArray
(
R
.
array
.
year_view_week_string_array
)[
week
];
canvas
.
drawText
(
text
,
x
+
width
/
2
,
y
+
mWeekTextBaseLine
,
mWeekTextPaint
);
}
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
)
{
return
false
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
)
{
}
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
)
{
float
baselineY
=
mTextBaseLine
+
y
;
int
cx
=
x
+
mItemWidth
/
2
;
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
hasScheme
?
mSchemeTextPaint
:
mSelectTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/LunarCalendar.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.text.TextUtils
;
import
com.sobot.widget.R
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 农历计算相关
*/
@SuppressWarnings
(
"all"
)
public
final
class
LunarCalendar
{
static
void
init
(
Context
context
)
{
if
(
MONTH_STR
!=
null
)
{
return
;
}
TrunkBranchAnnals
.
init
(
context
);
SolarTermUtil
.
init
(
context
);
MONTH_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
lunar_first_of_month
);
TRADITION_FESTIVAL_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
tradition_festival
);
DAY_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
lunar_str
);
SPECIAL_FESTIVAL_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
special_festivals
);
SOLAR_CALENDAR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
solar_festival
);
}
/**
* 农历月份第一天转写
*/
private
static
String
[]
MONTH_STR
=
null
;
/**
* 传统农历节日
*/
private
static
String
[]
TRADITION_FESTIVAL_STR
=
null
;
/**
* 农历大写
*/
private
static
String
[]
DAY_STR
=
null
;
/**
* 特殊节日的数组
*/
private
static
String
[]
SPECIAL_FESTIVAL_STR
=
null
;
/**
* 特殊节日、母亲节和父亲节,感恩节等
*/
@SuppressLint
(
"UseSparseArrays"
)
private
static
final
Map
<
Integer
,
String
[]>
SPECIAL_FESTIVAL
=
new
HashMap
<>();
/**
* 公历节日
*/
private
static
String
[]
SOLAR_CALENDAR
=
null
;
/**
* 保存每年24节气
*/
@SuppressLint
(
"UseSparseArrays"
)
private
static
final
Map
<
Integer
,
String
[]>
SOLAR_TERMS
=
new
HashMap
<>();
/**
* 返回传统农历节日
*
* @param year 农历年
* @param month 农历月
* @param day 农历日
* @return 返回传统农历节日
*/
private
static
String
getTraditionFestival
(
int
year
,
int
month
,
int
day
)
{
if
(
month
==
12
)
{
int
count
=
daysInLunarMonth
(
year
,
month
);
if
(
day
==
count
)
{
return
TRADITION_FESTIVAL_STR
[
0
];
//除夕
}
}
String
text
=
getString
(
month
,
day
);
String
festivalStr
=
""
;
for
(
String
festival
:
TRADITION_FESTIVAL_STR
)
{
if
(
festival
.
contains
(
text
))
{
festivalStr
=
festival
.
replace
(
text
,
""
);
break
;
}
}
return
festivalStr
;
}
/**
* 数字转换为汉字月份
*
* @param month 月
* @param leap 1==闰月
* @return 数字转换为汉字月份
*/
private
static
String
numToChineseMonth
(
int
month
,
int
leap
)
{
if
(
leap
==
1
)
{
return
"闰"
+
MONTH_STR
[
month
-
1
];
}
return
MONTH_STR
[
month
-
1
];
}
/**
* 数字转换为农历节日或者日期
*
* @param month 月
* @param day 日
* @param leap 1==闰月
* @return 数字转换为汉字日
*/
private
static
String
numToChinese
(
int
month
,
int
day
,
int
leap
)
{
if
(
day
==
1
)
{
return
numToChineseMonth
(
month
,
leap
);
}
return
DAY_STR
[
day
-
1
];
}
/**
* 用来表示1900年到2099年间农历年份的相关信息,共24位bit的16进制表示,其中:
* 1. 前4位表示该年闰哪个月;
* 2. 5-17位表示农历年份13个月的大小月分布,0表示小,1表示大;
* 3. 最后7位表示农历年首(正月初一)对应的公历日期。
* <p/>
* 以2014年的数据0x955ABF为例说明:
* 1001 0101 0101 1010 1011 1111
* 闰九月 农历正月初一对应公历1月31号
*/
private
static
final
int
[]
LUNAR_INFO
=
{
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
,
0x06e95
,
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
,
0x055c0
,
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
0x0a2e0
,
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
,
//2090-2099
0x0d520
};
/**
* 农历 year年month月的总天数,总共有13个月包括闰月
*
* @param year 将要计算的年份
* @param month 将要计算的月份
* @return 传回农历 year年month月的总天数
*/
public
static
int
daysInLunarMonth
(
int
year
,
int
month
)
{
if
((
LUNAR_INFO
[
year
-
CalendarViewDelegate
.
MIN_YEAR
]
&
(
0x10000
>>
month
))
==
0
)
return
29
;
else
return
30
;
}
/**
* 获取公历节日
*
* @param month 公历月份
* @param day 公历日期
* @return 公历节日
*/
private
static
String
gregorianFestival
(
int
month
,
int
day
)
{
String
text
=
getString
(
month
,
day
);
String
solar
=
""
;
for
(
String
aMSolarCalendar
:
SOLAR_CALENDAR
)
{
if
(
aMSolarCalendar
.
contains
(
text
))
{
solar
=
aMSolarCalendar
.
replace
(
text
,
""
);
break
;
}
}
return
solar
;
}
private
static
String
getString
(
int
month
,
int
day
)
{
return
(
month
>=
10
?
String
.
valueOf
(
month
)
:
"0"
+
month
)
+
(
day
>=
10
?
day
:
"0"
+
day
);
}
/**
* 返回24节气
*
* @param year 年
* @param month 月
* @param day 日
* @return 返回24节气
*/
private
static
String
getSolarTerm
(
int
year
,
int
month
,
int
day
)
{
if
(!
SOLAR_TERMS
.
containsKey
(
year
))
{
SOLAR_TERMS
.
put
(
year
,
SolarTermUtil
.
getSolarTerms
(
year
));
}
String
[]
solarTerm
=
SOLAR_TERMS
.
get
(
year
);
String
text
=
year
+
getString
(
month
,
day
);
String
solar
=
""
;
assert
solarTerm
!=
null
;
for
(
String
solarTermName
:
solarTerm
)
{
if
(
solarTermName
.
contains
(
text
))
{
solar
=
solarTermName
.
replace
(
text
,
""
);
break
;
}
}
return
solar
;
}
/**
* 获取农历节日
*
* @param year 年
* @param month 月
* @param day 日
* @return 农历节日
*/
public
static
String
getLunarText
(
int
year
,
int
month
,
int
day
)
{
String
termText
=
LunarCalendar
.
getSolarTerm
(
year
,
month
,
day
);
String
solar
=
LunarCalendar
.
gregorianFestival
(
month
,
day
);
if
(!
TextUtils
.
isEmpty
(
solar
))
return
solar
;
if
(!
TextUtils
.
isEmpty
(
termText
))
return
termText
;
int
[]
lunar
=
LunarUtil
.
solarToLunar
(
year
,
month
,
day
);
String
festival
=
getTraditionFestival
(
lunar
[
0
],
lunar
[
1
],
lunar
[
2
]);
if
(!
TextUtils
.
isEmpty
(
festival
))
return
festival
;
return
LunarCalendar
.
numToChinese
(
lunar
[
1
],
lunar
[
2
],
lunar
[
3
]);
}
/**
* 获取特殊计算方式的节日
* 如:每年五月的第二个星期日为母亲节,六月的第三个星期日为父亲节
* 每年11月第四个星期四定为"感恩节"
*
* @param year year
* @param month month
* @param day day
* @return 获取西方节日
*/
private
static
String
getSpecialFestival
(
int
year
,
int
month
,
int
day
)
{
if
(!
SPECIAL_FESTIVAL
.
containsKey
(
year
))
{
SPECIAL_FESTIVAL
.
put
(
year
,
getSpecialFestivals
(
year
));
}
String
[]
specialFestivals
=
SPECIAL_FESTIVAL
.
get
(
year
);
String
text
=
year
+
getString
(
month
,
day
);
String
solar
=
""
;
assert
specialFestivals
!=
null
;
for
(
String
special
:
specialFestivals
)
{
if
(
special
.
contains
(
text
))
{
solar
=
special
.
replace
(
text
,
""
);
break
;
}
}
return
solar
;
}
/**
* 获取每年的母亲节和父亲节和感恩节
* 特殊计算方式的节日
*
* @param year 年
* @return 获取每年的母亲节和父亲节、感恩节
*/
private
static
String
[]
getSpecialFestivals
(
int
year
)
{
String
[]
festivals
=
new
String
[
3
];
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
date
.
set
(
year
,
4
,
1
);
int
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
int
startDiff
=
7
-
week
+
1
;
if
(
startDiff
==
7
)
{
festivals
[
0
]
=
dateToString
(
year
,
5
,
startDiff
+
1
)
+
SPECIAL_FESTIVAL_STR
[
0
];
}
else
{
festivals
[
0
]
=
dateToString
(
year
,
5
,
startDiff
+
7
+
1
)
+
SPECIAL_FESTIVAL_STR
[
0
];
}
date
.
set
(
year
,
5
,
1
);
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
startDiff
=
7
-
week
+
1
;
if
(
startDiff
==
7
)
{
festivals
[
1
]
=
dateToString
(
year
,
6
,
startDiff
+
7
+
1
)
+
SPECIAL_FESTIVAL_STR
[
1
];
}
else
{
festivals
[
1
]
=
dateToString
(
year
,
6
,
startDiff
+
7
+
7
+
1
)
+
SPECIAL_FESTIVAL_STR
[
1
];
}
date
.
set
(
year
,
10
,
1
);
week
=
date
.
get
(
java
.
util
.
Calendar
.
DAY_OF_WEEK
);
startDiff
=
7
-
week
+
1
;
if
(
startDiff
<=
2
)
{
festivals
[
2
]
=
dateToString
(
year
,
11
,
startDiff
+
21
+
5
)
+
SPECIAL_FESTIVAL_STR
[
2
];
}
else
{
festivals
[
2
]
=
dateToString
(
year
,
11
,
startDiff
+
14
+
5
)
+
SPECIAL_FESTIVAL_STR
[
2
];
}
return
festivals
;
}
private
static
String
dateToString
(
int
year
,
int
month
,
int
day
)
{
return
year
+
getString
(
month
,
day
);
}
/**
* 初始化各种农历、节日
*
* @param calendar calendar
*/
public
static
void
setupLunarCalendar
(
Calendar
calendar
)
{
int
year
=
calendar
.
getYear
();
int
month
=
calendar
.
getMonth
();
int
day
=
calendar
.
getDay
();
calendar
.
setWeekend
(
CalendarUtil
.
isWeekend
(
calendar
));
calendar
.
setWeek
(
CalendarUtil
.
getWeekFormCalendar
(
calendar
));
Calendar
lunarCalendar
=
new
Calendar
();
calendar
.
setLunarCalendar
(
lunarCalendar
);
int
[]
lunar
=
LunarUtil
.
solarToLunar
(
year
,
month
,
day
);
lunarCalendar
.
setYear
(
lunar
[
0
]);
lunarCalendar
.
setMonth
(
lunar
[
1
]);
lunarCalendar
.
setDay
(
lunar
[
2
]);
calendar
.
setLeapYear
(
CalendarUtil
.
isLeapYear
(
year
));
if
(
lunar
[
3
]
==
1
)
{
//如果是闰月
calendar
.
setLeapMonth
(
lunar
[
1
]);
lunarCalendar
.
setLeapMonth
(
lunar
[
1
]);
}
String
solarTerm
=
LunarCalendar
.
getSolarTerm
(
year
,
month
,
day
);
String
gregorian
=
LunarCalendar
.
gregorianFestival
(
month
,
day
);
String
festival
=
getTraditionFestival
(
lunar
[
0
],
lunar
[
1
],
lunar
[
2
]);
String
lunarText
=
LunarCalendar
.
numToChinese
(
lunar
[
1
],
lunar
[
2
],
lunar
[
3
]);
if
(
TextUtils
.
isEmpty
(
gregorian
))
{
gregorian
=
getSpecialFestival
(
year
,
month
,
day
);
}
calendar
.
setSolarTerm
(
solarTerm
);
calendar
.
setGregorianFestival
(
gregorian
);
calendar
.
setTraditionFestival
(
festival
);
lunarCalendar
.
setTraditionFestival
(
festival
);
lunarCalendar
.
setSolarTerm
(
solarTerm
);
if
(!
TextUtils
.
isEmpty
(
solarTerm
))
{
calendar
.
setLunar
(
solarTerm
);
}
else
if
(!
TextUtils
.
isEmpty
(
gregorian
))
{
calendar
.
setLunar
(
gregorian
);
}
else
if
(!
TextUtils
.
isEmpty
(
festival
))
{
calendar
.
setLunar
(
festival
);
}
else
{
calendar
.
setLunar
(
lunarText
);
}
lunarCalendar
.
setLunar
(
lunarText
);
}
/**
* 获取农历节日
*
* @param calendar calendar
* @return 获取农历节日
*/
public
static
String
getLunarText
(
Calendar
calendar
)
{
return
getLunarText
(
calendar
.
getYear
(),
calendar
.
getMonth
(),
calendar
.
getDay
());
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/LunarUtil.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
/**
* 农历计算方法
*/
public
final
class
LunarUtil
{
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
=
{
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
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
);
}
private
static
int
[]
solarFromInt
(
long
g
)
{
long
y
=
(
10000
*
g
+
14780
)
/
3652425
;
long
ddd
=
g
-
(
365
*
y
+
y
/
4
-
y
/
100
+
y
/
400
);
if
(
ddd
<
0
)
{
y
--;
ddd
=
g
-
(
365
*
y
+
y
/
4
-
y
/
100
+
y
/
400
);
}
long
mi
=
(
100
*
ddd
+
52
)
/
3060
;
long
mm
=
(
mi
+
2
)
%
12
+
1
;
y
=
y
+
(
mi
+
2
)
/
12
;
long
dd
=
ddd
-
(
mi
*
306
+
5
)
/
10
+
1
;
int
[]
solar
=
new
int
[
4
];
solar
[
0
]
=
(
int
)
y
;
solar
[
1
]
=
(
int
)
mm
;
solar
[
2
]
=
(
int
)
dd
;
return
solar
;
}
/**
* 公历转农历 Solar To Lunar
*
* @param year 公历年
* @param month 公历月
* @param day 公历日
* @return [0]农历年 [1]农历月 [2]农历日 [3]是否闰月 0 false : 1 true
*/
@SuppressWarnings
(
"all"
)
public
static
int
[]
solarToLunar
(
int
year
,
int
month
,
int
day
)
{
int
[]
lunarInt
=
new
int
[
4
];
int
index
=
year
-
SOLAR
[
0
];
int
data
=
(
year
<<
9
)
|
(
month
<<
5
)
|
(
day
);
int
solar11
;
if
(
SOLAR
[
index
]
>
data
)
{
index
--;
}
solar11
=
SOLAR
[
index
];
int
y
=
getBitInt
(
solar11
,
12
,
9
);
int
m
=
getBitInt
(
solar11
,
4
,
5
);
int
d
=
getBitInt
(
solar11
,
5
,
0
);
long
offset
=
solarToInt
(
year
,
month
,
day
)
-
solarToInt
(
y
,
m
,
d
);
int
days
=
LUNAR_MONTH_DAYS
[
index
];
int
leap
=
getBitInt
(
days
,
4
,
13
);
int
lunarY
=
index
+
SOLAR
[
0
];
int
lunarM
=
1
;
int
lunarD
;
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
);
lunarInt
[
0
]
=
lunarY
;
lunarInt
[
1
]
=
lunarM
;
lunarInt
[
3
]
=
0
;
if
(
leap
!=
0
&&
lunarM
>
leap
)
{
lunarInt
[
1
]
=
lunarM
-
1
;
if
(
lunarM
==
leap
+
1
)
{
lunarInt
[
3
]
=
1
;
}
}
lunarInt
[
2
]
=
lunarD
;
return
lunarInt
;
}
/**
* 农历转公历
*
* @param lunarYear 农历年
* @param lunarMonth 农历月
* @param lunarDay 农历天
* @param isLeap 是否是闰年 0 false : 1 true
* @return [0]新历年 [1]新历月 [2]新历日 [3]是否闰月 0 false : 1 true
*/
@SuppressWarnings
(
"unused"
)
public
static
int
[]
lunarToSolar
(
int
lunarYear
,
int
lunarMonth
,
int
lunarDay
,
boolean
isLeap
)
{
int
days
=
LUNAR_MONTH_DAYS
[
lunarYear
-
LUNAR_MONTH_DAYS
[
0
]];
int
leap
=
getBitInt
(
days
,
4
,
13
);
int
offset
=
0
;
int
loop
=
leap
;
if
(!
isLeap
)
{
if
(
lunarMonth
<=
leap
||
leap
==
0
)
{
loop
=
lunarMonth
-
1
;
}
else
{
loop
=
lunarMonth
;
}
}
for
(
int
i
=
0
;
i
<
loop
;
i
++)
{
offset
+=
getBitInt
(
days
,
1
,
12
-
i
)
==
1
?
30
:
29
;
}
offset
+=
lunarDay
;
int
solar11
=
SOLAR
[
lunarYear
-
SOLAR
[
0
]];
int
y
=
getBitInt
(
solar11
,
12
,
9
);
int
m
=
getBitInt
(
solar11
,
4
,
5
);
int
d
=
getBitInt
(
solar11
,
5
,
0
);
return
solarFromInt
(
solarToInt
(
y
,
m
,
d
)
+
offset
-
1
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/Month.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
java.io.Serializable
;
@SuppressWarnings
(
"unused"
)
final
class
Month
implements
Serializable
{
private
int
diff
;
//日期偏移
private
int
count
;
private
int
month
;
private
int
year
;
int
getDiff
()
{
return
diff
;
}
void
setDiff
(
int
diff
)
{
this
.
diff
=
diff
;
}
int
getCount
()
{
return
count
;
}
void
setCount
(
int
count
)
{
this
.
count
=
count
;
}
int
getMonth
()
{
return
month
;
}
void
setMonth
(
int
month
)
{
this
.
month
=
month
;
}
int
getYear
()
{
return
year
;
}
void
setYear
(
int
year
)
{
this
.
year
=
year
;
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/MonthView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 月视图基础控件,可自由继承实现
*/
public
abstract
class
MonthView
extends
BaseMonthView
{
public
MonthView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mLineCount
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
int
count
=
mLineCount
*
7
;
int
d
=
0
;
for
(
int
i
=
0
;
i
<
mLineCount
;
i
++)
{
for
(
int
j
=
0
;
j
<
7
;
j
++)
{
Calendar
calendar
=
mItems
.
get
(
d
);
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
)
{
if
(
d
>
mItems
.
size
()
-
mNextDiff
)
{
return
;
}
if
(!
calendar
.
isCurrentMonth
())
{
++
d
;
continue
;
}
}
else
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_FIT_MONTH
)
{
if
(
d
>=
count
)
{
return
;
}
}
draw
(
canvas
,
calendar
,
i
,
j
,
d
);
++
d
;
}
}
}
/**
* 开始绘制
*
* @param canvas canvas
* @param calendar 对应日历
* @param i i
* @param j j
* @param d d
*/
private
void
draw
(
Canvas
canvas
,
Calendar
calendar
,
int
i
,
int
j
,
int
d
)
{
int
x
=
j
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
int
y
=
i
*
mItemHeight
;
onLoopStart
(
x
,
y
);
boolean
isSelected
=
d
==
mCurrentItem
;
boolean
hasScheme
=
calendar
.
hasScheme
();
if
(
hasScheme
)
{
//标记的日子
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
true
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
y
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
false
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
y
,
hasScheme
,
isSelected
);
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
&&
!
calendar
.
isCurrentMonth
())
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarOutOfRange
(
calendar
);
}
return
;
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(!
calendar
.
isCurrentMonth
()
&&
mMonthViewPager
!=
null
)
{
int
cur
=
mMonthViewPager
.
getCurrentItem
();
int
position
=
mCurrentItem
<
7
?
cur
-
1
:
cur
+
1
;
mMonthViewPager
.
setCurrentItem
(
position
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
if
(
calendar
.
isCurrentMonth
())
{
mParentLayout
.
updateSelectPosition
(
mItems
.
indexOf
(
calendar
));
}
else
{
mParentLayout
.
updateSelectWeek
(
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
()));
}
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
true
);
}
}
@Override
public
boolean
onLongClick
(
View
v
)
{
if
(
mDelegate
.
mCalendarLongClickListener
==
null
)
return
false
;
if
(!
isClick
)
{
return
false
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
false
;
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
&&
!
calendar
.
isCurrentMonth
())
{
return
false
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
false
;
}
boolean
isCalendarInRange
=
isInRange
(
calendar
);
if
(!
isCalendarInRange
)
{
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClickOutOfRange
(
calendar
);
}
return
true
;
}
if
(
mDelegate
.
isPreventLongPressedSelected
())
{
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClick
(
calendar
);
}
return
true
;
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(!
calendar
.
isCurrentMonth
()
&&
mMonthViewPager
!=
null
)
{
int
cur
=
mMonthViewPager
.
getCurrentItem
();
int
position
=
mCurrentItem
<
7
?
cur
-
1
:
cur
+
1
;
mMonthViewPager
.
setCurrentItem
(
position
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
if
(
calendar
.
isCurrentMonth
())
{
mParentLayout
.
updateSelectPosition
(
mItems
.
indexOf
(
calendar
));
}
else
{
mParentLayout
.
updateSelectWeek
(
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
()));
}
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
true
);
}
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClick
(
calendar
);
}
invalidate
();
return
true
;
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return 是否绘制onDrawScheme,true or false
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
);
/**
* 绘制标记的日期,这里可以是背景色,标记色什么的
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/MonthViewPager.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.v4.view.PagerAdapter
;
import
android.support.v4.view.ViewPager
;
import
android.util.AttributeSet
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
java.lang.reflect.Constructor
;
import
java.util.List
;
/**
* 月份切换ViewPager,自定义适应高度
*/
public
final
class
MonthViewPager
extends
ViewPager
{
private
boolean
isUpdateMonthView
;
private
int
mMonthCount
;
private
CalendarViewDelegate
mDelegate
;
private
int
mNextViewHeight
,
mPreViewHeight
,
mCurrentViewHeight
;
CalendarLayout
mParentLayout
;
WeekViewPager
mWeekPager
;
WeekBar
mWeekBar
;
/**
* 是否使用滚动到某一天
*/
private
boolean
isUsingScrollToCalendar
=
false
;
public
MonthViewPager
(
Context
context
)
{
this
(
context
,
null
);
}
public
MonthViewPager
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
/**
* 初始化
*
* @param delegate delegate
*/
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
updateMonthViewHeight
(
mDelegate
.
getCurrentDay
().
getYear
(),
mDelegate
.
getCurrentDay
().
getMonth
());
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
mCurrentViewHeight
;
setLayoutParams
(
params
);
init
();
}
/**
* 初始化
*/
private
void
init
()
{
mMonthCount
=
12
*
(
mDelegate
.
getMaxYear
()
-
mDelegate
.
getMinYear
())
-
mDelegate
.
getMinYearMonth
()
+
1
+
mDelegate
.
getMaxYearMonth
();
setAdapter
(
new
MonthViewPagerAdapter
());
addOnPageChangeListener
(
new
OnPageChangeListener
()
{
@Override
public
void
onPageScrolled
(
int
position
,
float
positionOffset
,
int
positionOffsetPixels
)
{
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
return
;
}
int
height
;
if
(
position
<
getCurrentItem
())
{
//右滑-1
height
=
(
int
)
((
mPreViewHeight
)
*
(
1
-
positionOffset
)
+
mCurrentViewHeight
*
positionOffset
);
}
else
{
//左滑+!
height
=
(
int
)
((
mCurrentViewHeight
)
*
(
1
-
positionOffset
)
+
(
mNextViewHeight
)
*
positionOffset
);
}
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
height
;
setLayoutParams
(
params
);
}
@Override
public
void
onPageSelected
(
int
position
)
{
Calendar
calendar
=
CalendarUtil
.
getFirstCalendarFromMonthViewPager
(
position
,
mDelegate
);
if
(
getVisibility
()
==
VISIBLE
)
{
if
(!
mDelegate
.
isShowYearSelectedLayout
&&
mDelegate
.
mIndexCalendar
!=
null
&&
calendar
.
getYear
()
!=
mDelegate
.
mIndexCalendar
.
getYear
()
&&
mDelegate
.
mYearChangeListener
!=
null
)
{
mDelegate
.
mYearChangeListener
.
onYearChange
(
calendar
.
getYear
());
}
mDelegate
.
mIndexCalendar
=
calendar
;
}
//月份改变事件
if
(
mDelegate
.
mMonthChangeListener
!=
null
)
{
mDelegate
.
mMonthChangeListener
.
onMonthChange
(
calendar
.
getYear
(),
calendar
.
getMonth
());
}
//周视图显示的时候就需要动态改变月视图高度
if
(
mWeekPager
.
getVisibility
()
==
VISIBLE
)
{
updateMonthViewHeight
(
calendar
.
getYear
(),
calendar
.
getMonth
());
return
;
}
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
if
(!
calendar
.
isCurrentMonth
())
{
mDelegate
.
mSelectedCalendar
=
calendar
;
}
else
{
mDelegate
.
mSelectedCalendar
=
CalendarUtil
.
getRangeEdgeCalendar
(
calendar
,
mDelegate
);
}
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
}
else
{
if
(
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
mDelegate
.
mSelectedStartRangeCalendar
.
isSameMonth
(
mDelegate
.
mIndexCalendar
))
{
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedStartRangeCalendar
;
}
else
{
if
(
calendar
.
isSameMonth
(
mDelegate
.
mSelectedCalendar
))
{
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
}
}
}
mDelegate
.
updateSelectCalendarScheme
();
if
(!
isUsingScrollToCalendar
&&
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
mWeekBar
.
onDateSelected
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
(),
false
);
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
mDelegate
.
mSelectedCalendar
,
false
);
}
}
BaseMonthView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
int
index
=
view
.
getSelectedIndex
(
mDelegate
.
mIndexCalendar
);
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
view
.
mCurrentItem
=
index
;
}
if
(
index
>=
0
&&
mParentLayout
!=
null
)
{
mParentLayout
.
updateSelectPosition
(
index
);
}
view
.
invalidate
();
}
mWeekPager
.
updateSelected
(
mDelegate
.
mIndexCalendar
,
false
);
updateMonthViewHeight
(
calendar
.
getYear
(),
calendar
.
getMonth
());
isUsingScrollToCalendar
=
false
;
}
@Override
public
void
onPageScrollStateChanged
(
int
state
)
{
}
});
}
/**
* 更新月视图的高度
*
* @param year year
* @param month month
*/
private
void
updateMonthViewHeight
(
int
year
,
int
month
)
{
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
//非动态高度就不需要了
mCurrentViewHeight
=
6
*
mDelegate
.
getCalendarItemHeight
();
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
mCurrentViewHeight
;
return
;
}
if
(
mParentLayout
!=
null
)
{
if
(
getVisibility
()
!=
VISIBLE
)
{
//如果已经显示周视图,则需要动态改变月视图高度,否则显示就有bug
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
setLayoutParams
(
params
);
}
mParentLayout
.
updateContentViewTranslateY
();
}
mCurrentViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
if
(
month
==
1
)
{
mPreViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
-
1
,
12
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
2
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
else
{
mPreViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
-
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
if
(
month
==
12
)
{
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
+
1
,
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
else
{
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
+
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
}
}
/**
* 刷新
*/
void
notifyDataSetChanged
()
{
mMonthCount
=
12
*
(
mDelegate
.
getMaxYear
()
-
mDelegate
.
getMinYear
())
-
mDelegate
.
getMinYearMonth
()
+
1
+
mDelegate
.
getMaxYearMonth
();
notifyAdapterDataSetChanged
();
}
/**
* 更新月视图Class
*/
void
updateMonthViewClass
()
{
isUpdateMonthView
=
true
;
notifyAdapterDataSetChanged
();
isUpdateMonthView
=
false
;
}
/**
* 更新日期范围
*/
final
void
updateRange
()
{
isUpdateMonthView
=
true
;
notifyDataSetChanged
();
isUpdateMonthView
=
false
;
if
(
getVisibility
()
!=
VISIBLE
)
{
return
;
}
isUsingScrollToCalendar
=
false
;
Calendar
calendar
=
mDelegate
.
mSelectedCalendar
;
int
y
=
calendar
.
getYear
()
-
mDelegate
.
getMinYear
();
int
position
=
12
*
y
+
calendar
.
getMonth
()
-
mDelegate
.
getMinYearMonth
();
setCurrentItem
(
position
,
false
);
BaseMonthView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
setSelectedCalendar
(
mDelegate
.
mIndexCalendar
);
view
.
invalidate
();
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
updateSelectPosition
(
view
.
getSelectedIndex
(
mDelegate
.
mIndexCalendar
));
}
}
if
(
mParentLayout
!=
null
)
{
int
week
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
week
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
false
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
false
);
}
updateSelected
();
}
/**
* 滚动到指定日期
*
* @param year 年
* @param month 月
* @param day 日
* @param invokeListener 调用日期事件
*/
void
scrollToCalendar
(
int
year
,
int
month
,
int
day
,
boolean
smoothScroll
,
boolean
invokeListener
)
{
isUsingScrollToCalendar
=
true
;
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
year
);
calendar
.
setMonth
(
month
);
calendar
.
setDay
(
day
);
calendar
.
setCurrentDay
(
calendar
.
equals
(
mDelegate
.
getCurrentDay
()));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
mDelegate
.
mIndexCalendar
=
calendar
;
mDelegate
.
mSelectedCalendar
=
calendar
;
mDelegate
.
updateSelectCalendarScheme
();
int
y
=
calendar
.
getYear
()
-
mDelegate
.
getMinYear
();
int
position
=
12
*
y
+
calendar
.
getMonth
()
-
mDelegate
.
getMinYearMonth
();
int
curItem
=
getCurrentItem
();
if
(
curItem
==
position
)
{
isUsingScrollToCalendar
=
false
;
}
setCurrentItem
(
position
,
smoothScroll
);
BaseMonthView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
setSelectedCalendar
(
mDelegate
.
mIndexCalendar
);
view
.
invalidate
();
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
updateSelectPosition
(
view
.
getSelectedIndex
(
mDelegate
.
mIndexCalendar
));
}
}
if
(
mParentLayout
!=
null
)
{
int
week
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
week
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
invokeListener
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
false
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
false
);
}
updateSelected
();
}
/**
* 滚动到当前日期
*/
void
scrollToCurrent
(
boolean
smoothScroll
)
{
isUsingScrollToCalendar
=
true
;
int
position
=
12
*
(
mDelegate
.
getCurrentDay
().
getYear
()
-
mDelegate
.
getMinYear
())
+
mDelegate
.
getCurrentDay
().
getMonth
()
-
mDelegate
.
getMinYearMonth
();
int
curItem
=
getCurrentItem
();
if
(
curItem
==
position
)
{
isUsingScrollToCalendar
=
false
;
}
setCurrentItem
(
position
,
smoothScroll
);
BaseMonthView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
setSelectedCalendar
(
mDelegate
.
getCurrentDay
());
view
.
invalidate
();
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
updateSelectPosition
(
view
.
getSelectedIndex
(
mDelegate
.
getCurrentDay
()));
}
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
getVisibility
()
==
VISIBLE
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
mDelegate
.
mSelectedCalendar
,
false
);
}
}
/**
* 获取当前月份数据
*
* @return 获取当前月份数据
*/
List
<
Calendar
>
getCurrentMonthCalendars
()
{
BaseMonthView
view
=
findViewWithTag
(
getCurrentItem
());
if
(
view
==
null
)
{
return
null
;
}
return
view
.
mItems
;
}
/**
* 更新为默认选择模式
*/
void
updateDefaultSelect
()
{
BaseMonthView
view
=
findViewWithTag
(
getCurrentItem
());
if
(
view
!=
null
)
{
int
index
=
view
.
getSelectedIndex
(
mDelegate
.
mSelectedCalendar
);
view
.
mCurrentItem
=
index
;
if
(
index
>=
0
&&
mParentLayout
!=
null
)
{
mParentLayout
.
updateSelectPosition
(
index
);
}
view
.
invalidate
();
}
}
/**
* 更新选择效果
*/
void
updateSelected
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
view
.
invalidate
();
}
}
/**
* 更新字体颜色大小
*/
final
void
updateStyle
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
updateStyle
();
view
.
invalidate
();
}
}
/**
* 更新标记日期
*/
void
updateScheme
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
update
();
}
}
/**
* 更新当前日期,夜间过度的时候调用这个函数,一般不需要调用
*/
void
updateCurrentDate
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
updateCurrentDate
();
}
}
/**
* 更新显示模式
*/
void
updateShowMode
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
updateShowMode
();
view
.
requestLayout
();
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ALL_MONTH
)
{
mCurrentViewHeight
=
6
*
mDelegate
.
getCalendarItemHeight
();
mNextViewHeight
=
mCurrentViewHeight
;
mPreViewHeight
=
mCurrentViewHeight
;
}
else
{
updateMonthViewHeight
(
mDelegate
.
mSelectedCalendar
.
getYear
(),
mDelegate
.
mSelectedCalendar
.
getMonth
());
}
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
mCurrentViewHeight
;
setLayoutParams
(
params
);
if
(
mParentLayout
!=
null
)
{
mParentLayout
.
updateContentViewTranslateY
();
}
}
/**
* 更新周起始
*/
void
updateWeekStart
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
updateWeekStart
();
view
.
requestLayout
();
}
updateMonthViewHeight
(
mDelegate
.
mSelectedCalendar
.
getYear
(),
mDelegate
.
mSelectedCalendar
.
getMonth
());
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
mCurrentViewHeight
;
setLayoutParams
(
params
);
if
(
mParentLayout
!=
null
)
{
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
mDelegate
.
mSelectedCalendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
updateSelected
();
}
/**
* 更新高度
*/
final
void
updateItemHeight
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
updateItemHeight
();
view
.
requestLayout
();
}
int
year
=
mDelegate
.
mIndexCalendar
.
getYear
();
int
month
=
mDelegate
.
mIndexCalendar
.
getMonth
();
mCurrentViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
if
(
month
==
1
)
{
mPreViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
-
1
,
12
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
2
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
else
{
mPreViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
-
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
if
(
month
==
12
)
{
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
+
1
,
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
else
{
mNextViewHeight
=
CalendarUtil
.
getMonthViewHeight
(
year
,
month
+
1
,
mDelegate
.
getCalendarItemHeight
(),
mDelegate
.
getWeekStart
(),
mDelegate
.
getMonthViewShowMode
());
}
}
ViewGroup
.
LayoutParams
params
=
getLayoutParams
();
params
.
height
=
mCurrentViewHeight
;
setLayoutParams
(
params
);
}
/**
* 清除选择范围
*/
final
void
clearSelectRange
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
invalidate
();
}
}
/**
* 清除单选选择
*/
final
void
clearSingleSelect
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
mCurrentItem
=
-
1
;
view
.
invalidate
();
}
}
/**
* 清除单选选择
*/
final
void
clearMultiSelect
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseMonthView
view
=
(
BaseMonthView
)
getChildAt
(
i
);
view
.
mCurrentItem
=
-
1
;
view
.
invalidate
();
}
}
private
void
notifyAdapterDataSetChanged
()
{
if
(
getAdapter
()
==
null
)
{
return
;
}
getAdapter
().
notifyDataSetChanged
();
}
@SuppressLint
(
"ClickableViewAccessibility"
)
@Override
public
boolean
onTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isMonthViewScrollable
()
&&
super
.
onTouchEvent
(
ev
);
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isMonthViewScrollable
()
&&
super
.
onInterceptTouchEvent
(
ev
);
}
@Override
public
void
setCurrentItem
(
int
item
)
{
setCurrentItem
(
item
,
true
);
}
@Override
public
void
setCurrentItem
(
int
item
,
boolean
smoothScroll
)
{
if
(
Math
.
abs
(
getCurrentItem
()
-
item
)
>
1
)
{
super
.
setCurrentItem
(
item
,
false
);
}
else
{
super
.
setCurrentItem
(
item
,
smoothScroll
);
}
}
/**
* 日历卡月份Adapter
*/
private
final
class
MonthViewPagerAdapter
extends
PagerAdapter
{
@Override
public
int
getCount
()
{
return
mMonthCount
;
}
@Override
public
int
getItemPosition
(
@NonNull
Object
object
)
{
return
isUpdateMonthView
?
POSITION_NONE
:
super
.
getItemPosition
(
object
);
}
@Override
public
boolean
isViewFromObject
(
View
view
,
@NonNull
Object
object
)
{
return
view
.
equals
(
object
);
}
@NonNull
@Override
public
Object
instantiateItem
(
@NonNull
ViewGroup
container
,
int
position
)
{
int
year
=
(
position
+
mDelegate
.
getMinYearMonth
()
-
1
)
/
12
+
mDelegate
.
getMinYear
();
int
month
=
(
position
+
mDelegate
.
getMinYearMonth
()
-
1
)
%
12
+
1
;
BaseMonthView
view
;
try
{
Constructor
constructor
=
mDelegate
.
getMonthViewClass
().
getConstructor
(
Context
.
class
);
view
=
(
BaseMonthView
)
constructor
.
newInstance
(
getContext
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
new
DefaultMonthView
(
getContext
());
}
view
.
mMonthViewPager
=
MonthViewPager
.
this
;
view
.
mParentLayout
=
mParentLayout
;
view
.
setup
(
mDelegate
);
view
.
setTag
(
position
);
view
.
initMonthWithDate
(
year
,
month
);
view
.
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
container
.
addView
(
view
);
return
view
;
}
@Override
public
void
destroyItem
(
@NonNull
ViewGroup
container
,
int
position
,
@NonNull
Object
object
)
{
BaseView
view
=
(
BaseView
)
object
;
view
.
onDestroy
();
container
.
removeView
(
view
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/MultiMonthView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 多选月视图
*/
public
abstract
class
MultiMonthView
extends
BaseMonthView
{
public
MultiMonthView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mLineCount
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
int
count
=
mLineCount
*
7
;
int
d
=
0
;
for
(
int
i
=
0
;
i
<
mLineCount
;
i
++)
{
for
(
int
j
=
0
;
j
<
7
;
j
++)
{
Calendar
calendar
=
mItems
.
get
(
d
);
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
)
{
if
(
d
>
mItems
.
size
()
-
mNextDiff
)
{
return
;
}
if
(!
calendar
.
isCurrentMonth
())
{
++
d
;
continue
;
}
}
else
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_FIT_MONTH
)
{
if
(
d
>=
count
)
{
return
;
}
}
draw
(
canvas
,
calendar
,
d
,
i
,
j
);
++
d
;
}
}
}
/**
* 开始绘制
*
* @param canvas canvas
* @param calendar 对应日历
* @param i i
* @param j j
*/
private
void
draw
(
Canvas
canvas
,
Calendar
calendar
,
int
calendarIndex
,
int
i
,
int
j
)
{
int
x
=
j
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
int
y
=
i
*
mItemHeight
;
onLoopStart
(
x
,
y
);
boolean
isSelected
=
isCalendarSelected
(
calendar
);
boolean
hasScheme
=
calendar
.
hasScheme
();
boolean
isPreSelected
=
isSelectPreCalendar
(
calendar
,
calendarIndex
);
boolean
isNextSelected
=
isSelectNextCalendar
(
calendar
,
calendarIndex
);
if
(
hasScheme
)
{
//标记的日子
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
true
,
isPreSelected
,
isNextSelected
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
y
,
true
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
false
,
isPreSelected
,
isNextSelected
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
y
,
hasScheme
,
isSelected
);
}
/**
* 日历是否被选中
*
* @param calendar calendar
* @return 日历是否被选中
*/
protected
boolean
isCalendarSelected
(
Calendar
calendar
)
{
return
!
onCalendarIntercept
(
calendar
)
&&
mDelegate
.
mSelectedCalendars
.
containsKey
(
calendar
.
toString
());
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
&&
!
calendar
.
isCurrentMonth
())
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onCalendarMultiSelectOutOfRange
(
calendar
);
}
return
;
}
String
key
=
calendar
.
toString
();
if
(
mDelegate
.
mSelectedCalendars
.
containsKey
(
key
))
{
mDelegate
.
mSelectedCalendars
.
remove
(
key
);
}
else
{
if
(
mDelegate
.
mSelectedCalendars
.
size
()
>=
mDelegate
.
getMaxMultiSelectSize
())
{
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onMultiSelectOutOfSize
(
calendar
,
mDelegate
.
getMaxMultiSelectSize
());
}
return
;
}
mDelegate
.
mSelectedCalendars
.
put
(
key
,
calendar
);
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(!
calendar
.
isCurrentMonth
()
&&
mMonthViewPager
!=
null
)
{
int
cur
=
mMonthViewPager
.
getCurrentItem
();
int
position
=
mCurrentItem
<
7
?
cur
-
1
:
cur
+
1
;
mMonthViewPager
.
setCurrentItem
(
position
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
if
(
calendar
.
isCurrentMonth
())
{
mParentLayout
.
updateSelectPosition
(
mItems
.
indexOf
(
calendar
));
}
else
{
mParentLayout
.
updateSelectWeek
(
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
()));
}
}
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onCalendarMultiSelect
(
calendar
,
mDelegate
.
mSelectedCalendars
.
size
(),
mDelegate
.
getMaxMultiSelectSize
());
}
}
@Override
public
boolean
onLongClick
(
View
v
)
{
return
false
;
}
/**
* 上一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 上一个日期是否选中
*/
protected
final
boolean
isSelectPreCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
preCalendar
;
if
(
calendarIndex
==
0
)
{
preCalendar
=
CalendarUtil
.
getPreCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
preCalendar
);
}
else
{
preCalendar
=
mItems
.
get
(
calendarIndex
-
1
);
}
return
isCalendarSelected
(
preCalendar
);
}
/**
* 下一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 下一个日期是否选中
*/
protected
final
boolean
isSelectNextCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
nextCalendar
;
if
(
calendarIndex
==
mItems
.
size
()
-
1
)
{
nextCalendar
=
CalendarUtil
.
getNextCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
nextCalendar
);
}
else
{
nextCalendar
=
mItems
.
get
(
calendarIndex
+
1
);
}
return
isCalendarSelected
(
nextCalendar
);
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme hasScheme 非标记的日期
* @param isSelectedPre 上一个日期是否选中
* @param isSelectedNext 下一个日期是否选中
* @return 是否继续绘制onDrawScheme,true or false
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
);
/**
* 绘制标记的日期,这里可以是背景色,标记色什么的
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
isSelected
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/MultiWeekView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 多选周视图
*/
public
abstract
class
MultiWeekView
extends
BaseWeekView
{
public
MultiWeekView
(
Context
context
)
{
super
(
context
);
}
/**
* 绘制日历文本
*
* @param canvas canvas
*/
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mItems
.
size
()
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
int
x
=
i
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
onLoopStart
(
x
);
Calendar
calendar
=
mItems
.
get
(
i
);
boolean
isSelected
=
isCalendarSelected
(
calendar
);
boolean
isPreSelected
=
isSelectPreCalendar
(
calendar
,
i
);
boolean
isNextSelected
=
isSelectNextCalendar
(
calendar
,
i
);
boolean
hasScheme
=
calendar
.
hasScheme
();
if
(
hasScheme
)
{
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
true
,
isPreSelected
,
isNextSelected
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
isSelected
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
false
,
isPreSelected
,
isNextSelected
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
hasScheme
,
isSelected
);
}
}
/**
* 日历是否被选中
*
* @param calendar calendar
* @return 日历是否被选中
*/
protected
boolean
isCalendarSelected
(
Calendar
calendar
)
{
return
!
onCalendarIntercept
(
calendar
)
&&
mDelegate
.
mSelectedCalendars
.
containsKey
(
calendar
.
toString
());
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onCalendarMultiSelectOutOfRange
(
calendar
);
}
return
;
}
String
key
=
calendar
.
toString
();
if
(
mDelegate
.
mSelectedCalendars
.
containsKey
(
key
))
{
mDelegate
.
mSelectedCalendars
.
remove
(
key
);
}
else
{
if
(
mDelegate
.
mSelectedCalendars
.
size
()
>=
mDelegate
.
getMaxMultiSelectSize
())
{
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onMultiSelectOutOfSize
(
calendar
,
mDelegate
.
getMaxMultiSelectSize
());
}
return
;
}
mDelegate
.
mSelectedCalendars
.
put
(
key
,
calendar
);
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
if
(
mDelegate
.
mCalendarMultiSelectListener
!=
null
)
{
mDelegate
.
mCalendarMultiSelectListener
.
onCalendarMultiSelect
(
calendar
,
mDelegate
.
mSelectedCalendars
.
size
(),
mDelegate
.
getMaxMultiSelectSize
());
}
invalidate
();
}
@Override
public
boolean
onLongClick
(
View
v
)
{
return
false
;
}
/**
* 上一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 上一个日期是否选中
*/
protected
final
boolean
isSelectPreCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
preCalendar
;
if
(
calendarIndex
==
0
)
{
preCalendar
=
CalendarUtil
.
getPreCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
preCalendar
);
}
else
{
preCalendar
=
mItems
.
get
(
calendarIndex
-
1
);
}
return
isCalendarSelected
(
preCalendar
);
}
/**
* 下一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 下一个日期是否选中
*/
protected
final
boolean
isSelectNextCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
nextCalendar
;
if
(
calendarIndex
==
mItems
.
size
()
-
1
)
{
nextCalendar
=
CalendarUtil
.
getNextCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
nextCalendar
);
}
else
{
nextCalendar
=
mItems
.
get
(
calendarIndex
+
1
);
}
return
isCalendarSelected
(
nextCalendar
);
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme hasScheme 非标记的日期
* @param isSelectedPre 上一个日期是否选中
* @param isSelectedNext 下一个日期是否选中
* @return 是否绘制 onDrawScheme
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
);
/**
* 绘制标记的日期
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
isSelected
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/RangeMonthView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 范围选择月视图
*/
public
abstract
class
RangeMonthView
extends
BaseMonthView
{
public
RangeMonthView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mLineCount
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
int
count
=
mLineCount
*
7
;
int
d
=
0
;
for
(
int
i
=
0
;
i
<
mLineCount
;
i
++)
{
for
(
int
j
=
0
;
j
<
7
;
j
++)
{
Calendar
calendar
=
mItems
.
get
(
d
);
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
)
{
if
(
d
>
mItems
.
size
()
-
mNextDiff
)
{
return
;
}
if
(!
calendar
.
isCurrentMonth
())
{
++
d
;
continue
;
}
}
else
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_FIT_MONTH
)
{
if
(
d
>=
count
)
{
return
;
}
}
draw
(
canvas
,
calendar
,
d
,
i
,
j
);
++
d
;
}
}
}
/**
* 开始绘制
*
* @param canvas canvas
* @param calendar 对应日历
* @param i i
* @param j j
*/
private
void
draw
(
Canvas
canvas
,
Calendar
calendar
,
int
calendarIndex
,
int
i
,
int
j
)
{
int
x
=
j
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
int
y
=
i
*
mItemHeight
;
onLoopStart
(
x
,
y
);
boolean
isSelected
=
isCalendarSelected
(
calendar
);
boolean
hasScheme
=
calendar
.
hasScheme
();
boolean
isPreSelected
=
isSelectPreCalendar
(
calendar
,
calendarIndex
);
boolean
isNextSelected
=
isSelectNextCalendar
(
calendar
,
calendarIndex
);
if
(
hasScheme
)
{
//标记的日子
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
true
,
isPreSelected
,
isNextSelected
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
y
,
true
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
false
,
isPreSelected
,
isNextSelected
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
y
,
hasScheme
,
isSelected
);
}
/**
* 日历是否被选中
*
* @param calendar calendar
* @return 日历是否被选中
*/
protected
boolean
isCalendarSelected
(
Calendar
calendar
)
{
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
)
{
return
false
;
}
if
(
onCalendarIntercept
(
calendar
))
{
return
false
;
}
if
(
mDelegate
.
mSelectedEndRangeCalendar
==
null
)
{
return
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
)
==
0
;
}
return
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
)
>=
0
&&
calendar
.
compareTo
(
mDelegate
.
mSelectedEndRangeCalendar
)
<=
0
;
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
mDelegate
.
getMonthViewShowMode
()
==
CalendarViewDelegate
.
MODE_ONLY_CURRENT_MONTH
&&
!
calendar
.
isCurrentMonth
())
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarSelectOutOfRange
(
calendar
);
}
return
;
}
//优先判断各种直接return的情况,减少代码深度
if
(
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
mDelegate
.
mSelectedEndRangeCalendar
==
null
)
{
int
minDiffer
=
CalendarUtil
.
differ
(
calendar
,
mDelegate
.
mSelectedStartRangeCalendar
);
if
(
minDiffer
>=
0
&&
mDelegate
.
getMinSelectRange
()
!=
-
1
&&
mDelegate
.
getMinSelectRange
()
>
minDiffer
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
calendar
,
true
);
}
return
;
}
else
if
(
mDelegate
.
getMaxSelectRange
()
!=
-
1
&&
mDelegate
.
getMaxSelectRange
()
<
CalendarUtil
.
differ
(
calendar
,
mDelegate
.
mSelectedStartRangeCalendar
)
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
calendar
,
false
);
}
return
;
}
}
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
||
mDelegate
.
mSelectedEndRangeCalendar
!=
null
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
{
int
compare
=
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
);
if
(
mDelegate
.
getMinSelectRange
()
==
-
1
&&
compare
<=
0
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
if
(
compare
<
0
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
if
(
compare
==
0
&&
mDelegate
.
getMinSelectRange
()
==
1
)
{
mDelegate
.
mSelectedEndRangeCalendar
=
calendar
;
}
else
{
mDelegate
.
mSelectedEndRangeCalendar
=
calendar
;
}
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(!
calendar
.
isCurrentMonth
()
&&
mMonthViewPager
!=
null
)
{
int
cur
=
mMonthViewPager
.
getCurrentItem
();
int
position
=
mCurrentItem
<
7
?
cur
-
1
:
cur
+
1
;
mMonthViewPager
.
setCurrentItem
(
position
);
}
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onMonthDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
if
(
calendar
.
isCurrentMonth
())
{
mParentLayout
.
updateSelectPosition
(
mItems
.
indexOf
(
calendar
));
}
else
{
mParentLayout
.
updateSelectWeek
(
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
()));
}
}
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarRangeSelect
(
calendar
,
mDelegate
.
mSelectedEndRangeCalendar
!=
null
);
}
}
@Override
public
boolean
onLongClick
(
View
v
)
{
return
false
;
}
/**
* 上一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 上一个日期是否选中
*/
protected
final
boolean
isSelectPreCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
preCalendar
;
if
(
calendarIndex
==
0
)
{
preCalendar
=
CalendarUtil
.
getPreCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
preCalendar
);
}
else
{
preCalendar
=
mItems
.
get
(
calendarIndex
-
1
);
}
return
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
isCalendarSelected
(
preCalendar
);
}
/**
* 下一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 下一个日期是否选中
*/
protected
final
boolean
isSelectNextCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
nextCalendar
;
if
(
calendarIndex
==
mItems
.
size
()
-
1
)
{
nextCalendar
=
CalendarUtil
.
getNextCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
nextCalendar
);
}
else
{
nextCalendar
=
mItems
.
get
(
calendarIndex
+
1
);
}
return
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
isCalendarSelected
(
nextCalendar
);
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme hasScheme 非标记的日期
* @param isSelectedPre 上一个日期是否选中
* @param isSelectedNext 下一个日期是否选中
* @return 是否继续绘制onDrawScheme,true or false
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
);
/**
* 绘制标记的日期,这里可以是背景色,标记色什么的
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
isSelected
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/RangeWeekView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 范围选择周视图
*/
public
abstract
class
RangeWeekView
extends
BaseWeekView
{
public
RangeWeekView
(
Context
context
)
{
super
(
context
);
}
/**
* 绘制日历文本
*
* @param canvas canvas
*/
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mItems
.
size
()
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
int
x
=
i
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
onLoopStart
(
x
);
Calendar
calendar
=
mItems
.
get
(
i
);
boolean
isSelected
=
isCalendarSelected
(
calendar
);
boolean
isPreSelected
=
isSelectPreCalendar
(
calendar
,
i
);
boolean
isNextSelected
=
isSelectNextCalendar
(
calendar
,
i
);
boolean
hasScheme
=
calendar
.
hasScheme
();
if
(
hasScheme
)
{
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
true
,
isPreSelected
,
isNextSelected
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
isSelected
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
false
,
isPreSelected
,
isNextSelected
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
hasScheme
,
isSelected
);
}
}
/**
* 日历是否被选中
*
* @param calendar calendar
* @return 日历是否被选中
*/
protected
boolean
isCalendarSelected
(
Calendar
calendar
)
{
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
)
{
return
false
;
}
if
(
onCalendarIntercept
(
calendar
))
{
return
false
;
}
if
(
mDelegate
.
mSelectedEndRangeCalendar
==
null
)
{
return
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
)
==
0
;
}
return
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
)
>=
0
&&
calendar
.
compareTo
(
mDelegate
.
mSelectedEndRangeCalendar
)
<=
0
;
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarSelectOutOfRange
(
calendar
);
}
return
;
}
//优先判断各种直接return的情况,减少代码深度
if
(
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
mDelegate
.
mSelectedEndRangeCalendar
==
null
)
{
int
minDiffer
=
CalendarUtil
.
differ
(
calendar
,
mDelegate
.
mSelectedStartRangeCalendar
);
if
(
minDiffer
>=
0
&&
mDelegate
.
getMinSelectRange
()
!=
-
1
&&
mDelegate
.
getMinSelectRange
()
>
minDiffer
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
calendar
,
true
);
}
return
;
}
else
if
(
mDelegate
.
getMaxSelectRange
()
!=
-
1
&&
mDelegate
.
getMaxSelectRange
()
<
CalendarUtil
.
differ
(
calendar
,
mDelegate
.
mSelectedStartRangeCalendar
)
+
1
)
{
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onSelectOutOfRange
(
calendar
,
false
);
}
return
;
}
}
if
(
mDelegate
.
mSelectedStartRangeCalendar
==
null
||
mDelegate
.
mSelectedEndRangeCalendar
!=
null
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
{
int
compare
=
calendar
.
compareTo
(
mDelegate
.
mSelectedStartRangeCalendar
);
if
(
mDelegate
.
getMinSelectRange
()
==
-
1
&&
compare
<=
0
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
if
(
compare
<
0
)
{
mDelegate
.
mSelectedStartRangeCalendar
=
calendar
;
mDelegate
.
mSelectedEndRangeCalendar
=
null
;
}
else
if
(
compare
==
0
&&
mDelegate
.
getMinSelectRange
()
==
1
)
{
mDelegate
.
mSelectedEndRangeCalendar
=
calendar
;
}
else
{
mDelegate
.
mSelectedEndRangeCalendar
=
calendar
;
}
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
if
(
mDelegate
.
mCalendarRangeSelectListener
!=
null
)
{
mDelegate
.
mCalendarRangeSelectListener
.
onCalendarRangeSelect
(
calendar
,
mDelegate
.
mSelectedEndRangeCalendar
!=
null
);
}
invalidate
();
}
@Override
public
boolean
onLongClick
(
View
v
)
{
return
false
;
}
/**
* 上一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 上一个日期是否选中
*/
protected
final
boolean
isSelectPreCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
preCalendar
;
if
(
calendarIndex
==
0
)
{
preCalendar
=
CalendarUtil
.
getPreCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
preCalendar
);
}
else
{
preCalendar
=
mItems
.
get
(
calendarIndex
-
1
);
}
return
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
isCalendarSelected
(
preCalendar
);
}
/**
* 下一个日期是否选中
*
* @param calendar 当前日期
* @param calendarIndex 当前位置
* @return 下一个日期是否选中
*/
protected
final
boolean
isSelectNextCalendar
(
Calendar
calendar
,
int
calendarIndex
)
{
Calendar
nextCalendar
;
if
(
calendarIndex
==
mItems
.
size
()
-
1
)
{
nextCalendar
=
CalendarUtil
.
getNextCalendar
(
calendar
);
mDelegate
.
updateCalendarScheme
(
nextCalendar
);
}
else
{
nextCalendar
=
mItems
.
get
(
calendarIndex
+
1
);
}
return
mDelegate
.
mSelectedStartRangeCalendar
!=
null
&&
isCalendarSelected
(
nextCalendar
);
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme hasScheme 非标记的日期
* @param isSelectedPre 上一个日期是否选中
* @param isSelectedNext 下一个日期是否选中
* @return 是否绘制 onDrawScheme
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelectedPre
,
boolean
isSelectedNext
);
/**
* 绘制标记的日期
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
isSelected
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/SimpleMonthView.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* 高仿魅族日历布局
*/
public
class
SimpleMonthView
extends
MonthView
{
private
int
mRadius
;
public
SimpleMonthView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onPreviewHook
()
{
mRadius
=
Math
.
min
(
mItemWidth
,
mItemHeight
)
/
5
*
2
;
mSchemePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
}
@Override
protected
void
onLoopStart
(
int
x
,
int
y
)
{
}
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
y
+
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
return
false
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
y
+
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSchemePaint
);
}
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
)
{
float
baselineY
=
mTextBaseLine
+
y
;
int
cx
=
x
+
mItemWidth
/
2
;
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
mSelectTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mSchemeTextPaint
:
mOtherMonthTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthTextPaint
:
mOtherMonthTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/SimpleWeekView.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
/**
* 简单周视图
*/
public
class
SimpleWeekView
extends
WeekView
{
private
int
mRadius
;
public
SimpleWeekView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
void
onPreviewHook
()
{
mRadius
=
Math
.
min
(
mItemWidth
,
mItemHeight
)
/
5
*
2
;
mSchemePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
}
@Override
protected
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSelectedPaint
);
return
false
;
}
@Override
protected
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
)
{
int
cx
=
x
+
mItemWidth
/
2
;
int
cy
=
mItemHeight
/
2
;
canvas
.
drawCircle
(
cx
,
cy
,
mRadius
,
mSchemePaint
);
}
@Override
protected
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
)
{
float
baselineY
=
mTextBaseLine
;
int
cx
=
x
+
mItemWidth
/
2
;
if
(
isSelected
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
mSelectTextPaint
);
}
else
if
(
hasScheme
)
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mSchemeTextPaint
:
mSchemeTextPaint
);
}
else
{
canvas
.
drawText
(
String
.
valueOf
(
calendar
.
getDay
()),
cx
,
baselineY
,
calendar
.
isCurrentDay
()
?
mCurDayTextPaint
:
calendar
.
isCurrentMonth
()
?
mCurMonthTextPaint
:
mCurMonthTextPaint
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/SolarTermUtil.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
com.sobot.widget.R
;
/**
* http://www.cnblogs.com/moodlxs/archive/2010/12/18/2345392.html
* 24节气计算公式,参考该博客实现
*/
@SuppressWarnings
(
"all"
)
public
final
class
SolarTermUtil
{
static
void
init
(
Context
context
)
{
SOLAR_TERMS
=
context
.
getResources
().
getStringArray
(
R
.
array
.
solar_term
);
}
/**
* 24节气
*/
private
static
String
SOLAR_TERMS
[]
=
null
;
/**
* 每弧度的角秒数
*/
private
static
final
double
SECOND_PER_RAD
=
180
*
3600
/
Math
.
PI
;
/**
* 每弧度的角度数
*/
private
static
final
double
ANGLE_PER_RAD
=
180
/
Math
.
PI
;
/**
* 日历计算
* 2000年前儒略日数(2000-1-1)
*/
private
static
final
double
J2000
=
2451545
;
/**
* 黄赤交角系数表
*/
private
static
final
double
H_C_ANGLE_TABLE
[]
=
{
0
,
50287.92262
,
111.24406
,
0.07699
,
-
0.23479
,
-
0.00178
,
0.00018
,
0.00001
};
/**
* 世界时与原子时之差计算表
*/
private
static
final
double
[]
DTS
=
{
-
4000
,
108371.7
,
-
13036.80
,
392.000
,
0.0000
,
-
500
,
17201.0
,
-
627.82
,
16.170
,
-
0.3413
,
-
150
,
12200.6
,
-
346.41
,
5.403
,
-
0.1593
,
150
,
9113.8
,
-
328.13
,
-
1.647
,
0.0377
,
500
,
5707.5
,
-
391.41
,
0.915
,
0.3145
,
900
,
2203.4
,
-
283.45
,
13.034
,
-
0.1778
,
1300
,
490.1
,
-
57.35
,
2.085
,
-
0.0072
,
1600
,
120.0
,
-
9.81
,
-
1.532
,
0.1403
,
1700
,
10.2
,
-
0.91
,
0.510
,
-
0.0370
,
1800
,
13.4
,
-
0.72
,
0.202
,
-
0.0193
,
1830
,
7.8
,
-
1.81
,
0.416
,
-
0.0247
,
1860
,
8.3
,
-
0.13
,
-
0.406
,
0.0292
,
1880
,
-
5.4
,
0.32
,
-
0.183
,
0.0173
,
1900
,
-
2.3
,
2.06
,
0.169
,
-
0.0135
,
1920
,
21.2
,
1.69
,
-
0.304
,
0.0167
,
1940
,
24.2
,
1.22
,
-
0.064
,
0.0031
,
1960
,
33.2
,
0.51
,
0.231
,
-
0.0109
,
1980
,
51.0
,
1.29
,
-
0.026
,
0.0032
,
2000
,
64.7
,
-
1.66
,
5.224
,
-
0.2905
,
2150
,
279.4
,
732.95
,
429.579
,
0.0158
,
6000
};
/**
* 离心率
*/
private
static
final
double
GXC_E
[]
=
{
0.016708634
,
-
0.000042037
,
-
0.0000001267
};
/**
* 近点
*/
private
static
final
double
GXC_P
[]
=
{
102.93735
/
ANGLE_PER_RAD
,
1.71946
/
ANGLE_PER_RAD
,
0.00046
/
ANGLE_PER_RAD
};
/**
* 太平黄经
*/
private
static
final
double
GXC_L
[]
=
{
280.4664567
/
ANGLE_PER_RAD
,
36000.76982779
/
ANGLE_PER_RAD
,
0.0003032028
/
ANGLE_PER_RAD
,
1
/
49931000
/
ANGLE_PER_RAD
,
-
1
/
153000000
/
ANGLE_PER_RAD
};
/**
* 光行差常数
*/
private
static
final
double
GXC_K
=
20.49552
/
SECOND_PER_RAD
;
/**
* 向下取整
*
* @param v v
* @return 取整数部分
*/
private
static
double
doubleFloor
(
double
v
)
{
v
=
Math
.
floor
(
v
);
if
(
v
<
0
)
return
v
+
1
;
return
v
;
}
/**
* 对超过0-2PI的角度转为0-2PI
*
* @param v v
* @return 对超过0-2PI的角度转为0-2PI
*/
private
static
double
rad2mrad
(
double
v
)
{
v
=
v
%
(
2
*
Math
.
PI
);
if
(
v
<
0
)
return
v
+
2
*
Math
.
PI
;
return
v
;
}
/**
* 计算世界时与原子时之差,传入年
*
* @param year 年
* @return 计算世界时与原子时之差
*/
private
static
double
worldTimeDiff
(
double
year
)
{
int
i
;
for
(
i
=
0
;
i
<
100
;
i
+=
5
)
if
(
year
<
DTS
[
i
+
5
]
||
i
==
95
)
break
;
double
t1
=
(
year
-
DTS
[
i
])
/
(
DTS
[
i
+
5
]
-
DTS
[
i
])
*
10
;
double
t2
=
t1
*
t1
;
double
t3
=
t2
*
t1
;
return
DTS
[
i
+
1
]
+
DTS
[
i
+
2
]
*
t1
+
DTS
[
i
+
3
]
*
t2
+
DTS
[
i
+
4
]
*
t3
;
}
/**
* 传入儒略日(J2000起算),计算UTC与原子时的差(单位:日)
*
* @param julian 儒略日
* @return 计算UTC与原子时的差
*/
private
static
double
atomTimeDiff
(
double
julian
)
{
return
worldTimeDiff
(
julian
/
365.2425
+
2000
)
/
86400.0
;
}
/**
* 公历转儒略日,UTC=1表示原日期是UTC
*
* @param UTC UTC
* @return 公历转儒略日, UTC=1表示原日期是UTC
*/
private
static
double
toJulian
(
Time
time
,
boolean
UTC
)
{
double
y
=
time
.
year
;
// 取出年月
double
m
=
time
.
month
;
double
n
=
0
;
if
(
m
<=
2
)
{
m
+=
12
;
y
--;
}
if
(
time
.
year
*
372
+
time
.
month
*
31
+
time
.
day
>=
588829
)
{
// 判断是否为格里高利历日1582*372+10*31+15
n
=
doubleFloor
(
y
/
100
);
n
=
2
-
n
+
doubleFloor
(
n
/
4
);
// 加百年闰
}
n
+=
doubleFloor
(
365.2500001
*
(
y
+
4716
));
// 加上年引起的偏移日数
n
+=
doubleFloor
(
30.6
*
(
m
+
1
))
+
time
.
day
;
// 加上月引起的偏移日数及日偏移数
n
+=
((
time
.
second
/
60
+
time
.
minute
)
/
60
+
time
.
hour
)
/
24
-
1524.5
;
if
(
UTC
)
return
n
+
atomTimeDiff
(
n
-
J2000
);
return
n
;
}
/**
* 儒略日数转公历,UTC=1表示目标公历是UTC
*
* @param jd jd
* @param UTC UTC
*/
@SuppressWarnings
(
"all"
)
private
static
Time
setFromJulian
(
double
jd
,
boolean
UTC
)
{
Time
time
=
new
Time
();
if
(
UTC
)
jd
-=
atomTimeDiff
(
jd
-
J2000
);
jd
+=
0.5
;
// 取得日数的整数部份A及小数部分F
double
A
=
doubleFloor
(
jd
);
double
F
=
jd
-
A
;
double
D
;
if
(
A
>
2299161
)
{
D
=
doubleFloor
((
A
-
1867216.25
)
/
36524.25
);
A
+=
1
+
D
-
doubleFloor
(
D
/
4
);
}
A
+=
1524
;
// 向前移4年零2个月
time
.
year
=
doubleFloor
((
A
-
122.1
)
/
365.25
);
// 年
D
=
A
-
doubleFloor
(
365.25
*
time
.
year
);
// 去除整年日数后余下日数
time
.
month
=
doubleFloor
(
D
/
30.6001
);
// 月数
time
.
day
=
D
-
doubleFloor
(
time
.
month
*
30.6001
);
// 去除整月日数后余下日数
time
.
year
-=
4716
;
time
.
month
--;
if
(
time
.
month
>
12
)
time
.
month
-=
12
;
if
(
time
.
month
<=
2
)
time
.
year
++;
// 日的小数转为时分秒
F
*=
24
;
time
.
hour
=
doubleFloor
(
F
);
F
-=
time
.
hour
;
F
*=
60
;
time
.
minute
=
doubleFloor
(
F
);
F
-=
time
.
minute
;
F
*=
60
;
time
.
second
=
F
;
return
time
;
}
/**
* 补岁差
*
* @param jd jd
* @param zb zb
*/
private
static
void
precession
(
double
jd
,
double
[]
zb
)
{
int
i
;
double
t
=
1
,
v
=
0
,
t1
=
jd
/
365250
;
for
(
i
=
1
;
i
<
8
;
i
++)
{
t
*=
t1
;
v
+=
H_C_ANGLE_TABLE
[
i
]
*
t
;
}
zb
[
0
]
=
rad2mrad
(
zb
[
0
]
+
(
v
+
2.9965
*
t1
)
/
SECOND_PER_RAD
);
}
/**
* 恒星周年光行差计算(黄道坐标中)
*
* @param t t
* @param zb zb
*/
private
static
void
addGxc
(
double
t
,
double
[]
zb
)
{
double
t1
=
t
/
36525
;
double
t2
=
t1
*
t1
;
double
t3
=
t2
*
t1
;
double
t4
=
t3
*
t1
;
double
L
=
GXC_L
[
0
]
+
GXC_L
[
1
]
*
t1
+
GXC_L
[
2
]
*
t2
+
GXC_L
[
3
]
*
t3
+
GXC_L
[
4
]
*
t4
;
double
p
=
GXC_P
[
0
]
+
GXC_P
[
1
]
*
t1
+
GXC_P
[
2
]
*
t2
;
double
e
=
GXC_E
[
0
]
+
GXC_E
[
1
]
*
t1
+
GXC_E
[
2
]
*
t2
;
double
dL
=
L
-
zb
[
0
],
dP
=
p
-
zb
[
0
];
zb
[
0
]
-=
GXC_K
*
(
Math
.
cos
(
dL
)
-
e
*
Math
.
cos
(
dP
))
/
Math
.
cos
(
zb
[
1
]);
zb
[
1
]
-=
GXC_K
*
Math
.
sin
(
zb
[
1
])
*
(
Math
.
sin
(
dL
)
-
e
*
Math
.
sin
(
dP
));
zb
[
0
]
=
rad2mrad
(
zb
[
0
]);
}
/**
* 章动计算
*/
private
static
final
double
nutB
[]
=
{
// 章动表
2.1824391966
,
-
33.757045954
,
0.0000362262
,
3.7340
E
-
08
,
-
2.8793
E
-
10
,
-
171996
,
-
1742
,
92025
,
89
,
3.5069406862
,
1256.663930738
,
0.0000105845
,
6.9813
E
-
10
,
-
2.2815
E
-
10
,
-
13187
,
-
16
,
5736
,
-
31
,
1.3375032491
,
16799.418221925
,
-
0.0000511866
,
6.4626
E
-
08
,
-
5.3543
E
-
10
,
-
2274
,
-
2
,
977
,
-
5
,
4.3648783932
,
-
67.514091907
,
0.0000724525
,
7.4681
E
-
08
,
-
5.7586
E
-
10
,
2062
,
2
,
-
895
,
5
,
0.0431251803
,
-
628.301955171
,
0.0000026820
,
6.5935
E
-
10
,
5.5705
E
-
11
,
-
1426
,
34
,
54
,
-
1
,
2.3555557435
,
8328.691425719
,
0.0001545547
,
2.5033
E
-
07
,
-
1.1863
E
-
09
,
712
,
1
,
-
7
,
0
,
3.4638155059
,
1884.965885909
,
0.0000079025
,
3.8785
E
-
11
,
-
2.8386
E
-
10
,
-
517
,
12
,
224
,
-
6
,
5.4382493597
,
16833.175267879
,
-
0.0000874129
,
2.7285
E
-
08
,
-
2.4750
E
-
10
,
-
386
,
-
4
,
200
,
0
,
3.6930589926
,
25128.109647645
,
0.0001033681
,
3.1496
E
-
07
,
-
1.7218
E
-
09
,
-
301
,
0
,
129
,
-
1
,
3.5500658664
,
628.361975567
,
0.0000132664
,
1.3575
E
-
09
,
-
1.7245
E
-
10
,
217
,
-
5
,
-
95
,
3
};
/**
* 计算黄经章动及交角章动
*
* @param t t
* @return 计算黄经章动及交角章动
*/
private
static
Nutation
nutation
(
double
t
)
{
Nutation
d
=
new
Nutation
();
d
.
Lon
=
0
;
d
.
Obl
=
0
;
t
/=
36525
;
double
c
,
t1
=
t
,
t2
=
t1
*
t1
,
t3
=
t2
*
t1
,
t4
=
t3
*
t1
;
// t5=t4*t1;
for
(
int
i
=
0
;
i
<
nutB
.
length
;
i
+=
9
)
{
c
=
nutB
[
i
]
+
nutB
[
i
+
1
]
*
t1
+
nutB
[
i
+
2
]
*
t2
+
nutB
[
i
+
3
]
*
t3
+
nutB
[
i
+
4
]
*
t4
;
d
.
Lon
+=
(
nutB
[
i
+
5
]
+
nutB
[
i
+
6
]
*
t
/
10
)
*
Math
.
sin
(
c
);
// 黄经章动
d
.
Obl
+=
(
nutB
[
i
+
7
]
+
nutB
[
i
+
8
]
*
t
/
10
)
*
Math
.
cos
(
c
);
// 交角章动
}
d
.
Lon
/=
SECOND_PER_RAD
*
10000
;
// 黄经章动
d
.
Obl
/=
SECOND_PER_RAD
*
10000
;
// 交角章动
return
d
;
}
//
/***************************************
* 如果用记事本查看此代码,请在"格式"菜单中去除"自动换行"
* E10是关于地球的,格式如下:
* 它是一个数组,每3个数看作一条记录,每条记录的3个数记为A,B,C
* rec=A*cos(B+C*t); 式中t是J2000起算的儒略千年数
* 每条记录的计算结果(即rec)取和即得地球的日心黄经的周期量L0
* E11格式如下: rec = A*cos*(B+C*t) *t, 取和后得泊松量L1
* E12格式如下: rec = A*cos*(B+C*t) *t*t, 取和后得泊松量L2
* E13格式如下: rec = A*cos*(B+C*t) *t*t*t, 取和后得泊松量L3
* 最后地球的地心黄经:L = L0+L1+L2+L3+...
* E20,E21,E22,E23...用于计算黄纬
* M10,M11等是关于月球的,参数的用法请阅读Mnn()函数
*****************************************/
//地球运动VSOP87参数
private
static
final
double
E10
[]
=
{
//黄经周期项
1.75347045673
,
0.00000000000
,
0.0000000000
,
0.03341656456
,
4.66925680417
,
6283.0758499914
,
0.00034894275
,
4.62610241759
,
12566.1516999828
,
0.00003417571
,
2.82886579606
,
3.5231183490
,
0.00003497056
,
2.74411800971
,
5753.3848848968
,
0.00003135896
,
3.62767041758
,
77713.7714681205
,
0.00002676218
,
4.41808351397
,
7860.4193924392
,
0.00002342687
,
6.13516237631
,
3930.2096962196
,
0.00001273166
,
2.03709655772
,
529.6909650946
,
0.00001324292
,
0.74246356352
,
11506.7697697936
,
0.00000901855
,
2.04505443513
,
26.2983197998
,
0.00001199167
,
1.10962944315
,
1577.3435424478
,
0.00000857223
,
3.50849156957
,
398.1490034082
,
0.00000779786
,
1.17882652114
,
5223.6939198022
,
0.00000990250
,
5.23268129594
,
5884.9268465832
,
0.00000753141
,
2.53339053818
,
5507.5532386674
,
0.00000505264
,
4.58292563052
,
18849.2275499742
,
0.00000492379
,
4.20506639861
,
775.5226113240
,
0.00000356655
,
2.91954116867
,
0.0673103028
,
0.00000284125
,
1.89869034186
,
796.2980068164
,
0.00000242810
,
0.34481140906
,
5486.7778431750
,
0.00000317087
,
5.84901952218
,
11790.6290886588
,
0.00000271039
,
0.31488607649
,
10977.0788046990
,
0.00000206160
,
4.80646606059
,
2544.3144198834
,
0.00000205385
,
1.86947813692
,
5573.1428014331
,
0.00000202261
,
2.45767795458
,
6069.7767545534
,
0.00000126184
,
1.08302630210
,
20.7753954924
,
0.00000155516
,
0.83306073807
,
213.2990954380
,
0.00000115132
,
0.64544911683
,
0.9803210682
,
0.00000102851
,
0.63599846727
,
4694.0029547076
,
0.00000101724
,
4.26679821365
,
7.1135470008
,
0.00000099206
,
6.20992940258
,
2146.1654164752
,
0.00000132212
,
3.41118275555
,
2942.4634232916
,
0.00000097607
,
0.68101272270
,
155.4203994342
,
0.00000085128
,
1.29870743025
,
6275.9623029906
,
0.00000074651
,
1.75508916159
,
5088.6288397668
,
0.00000101895
,
0.97569221824
,
15720.8387848784
,
0.00000084711
,
3.67080093025
,
71430.6956181291
,
0.00000073547
,
4.67926565481
,
801.8209311238
,
0.00000073874
,
3.50319443167
,
3154.6870848956
,
0.00000078756
,
3.03698313141
,
12036.4607348882
,
0.00000079637
,
1.80791330700
,
17260.1546546904
,
0.00000085803
,
5.98322631256
,
161000.6857376741
,
0.00000056963
,
2.78430398043
,
6286.5989683404
,
0.00000061148
,
1.81839811024
,
7084.8967811152
,
0.00000069627
,
0.83297596966
,
9437.7629348870
,
0.00000056116
,
4.38694880779
,
14143.4952424306
,
0.00000062449
,
3.97763880587
,
8827.3902698748
,
0.00000051145
,
0.28306864501
,
5856.4776591154
,
0.00000055577
,
3.47006009062
,
6279.5527316424
,
0.00000041036
,
5.36817351402
,
8429.2412664666
,
0.00000051605
,
1.33282746983
,
1748.0164130670
,
0.00000051992
,
0.18914945834
,
12139.5535091068
,
0.00000049000
,
0.48735065033
,
1194.4470102246
,
0.00000039200
,
6.16832995016
,
10447.3878396044
,
0.00000035566
,
1.77597314691
,
6812.7668150860
,
0.00000036770
,
6.04133859347
,
10213.2855462110
,
0.00000036596
,
2.56955238628
,
1059.3819301892
,
0.00000033291
,
0.59309499459
,
17789.8456197850
,
0.00000035954
,
1.70876111898
,
2352.8661537718
};
private
static
final
double
E11
[]
=
{
//黄经泊松1项
6283.31966747491
,
0.00000000000
,
0.0000000000
,
0.00206058863
,
2.67823455584
,
6283.0758499914
,
0.00004303430
,
2.63512650414
,
12566.1516999828
,
0.00000425264
,
1.59046980729
,
3.5231183490
,
0.00000108977
,
2.96618001993
,
1577.3435424478
,
0.00000093478
,
2.59212835365
,
18849.2275499742
,
0.00000119261
,
5.79557487799
,
26.2983197998
,
0.00000072122
,
1.13846158196
,
529.6909650946
,
0.00000067768
,
1.87472304791
,
398.1490034082
,
0.00000067327
,
4.40918235168
,
5507.5532386674
,
0.00000059027
,
2.88797038460
,
5223.6939198022
,
0.00000055976
,
2.17471680261
,
155.4203994342
,
0.00000045407
,
0.39803079805
,
796.2980068164
,
0.00000036369
,
0.46624739835
,
775.5226113240
,
0.00000028958
,
2.64707383882
,
7.1135470008
,
0.00000019097
,
1.84628332577
,
5486.7778431750
,
0.00000020844
,
5.34138275149
,
0.9803210682
,
0.00000018508
,
4.96855124577
,
213.2990954380
,
0.00000016233
,
0.03216483047
,
2544.3144198834
,
0.00000017293
,
2.99116864949
,
6275.9623029906
};
private
static
final
double
E12
[]
=
{
//黄经泊松2项
0.00052918870
,
0.00000000000
,
0.0000000000
,
0.00008719837
,
1.07209665242
,
6283.0758499914
,
0.00000309125
,
0.86728818832
,
12566.1516999828
,
0.00000027339
,
0.05297871691
,
3.5231183490
,
0.00000016334
,
5.18826691036
,
26.2983197998
,
0.00000015752
,
3.68457889430
,
155.4203994342
,
0.00000009541
,
0.75742297675
,
18849.2275499742
,
0.00000008937
,
2.05705419118
,
77713.7714681205
,
0.00000006952
,
0.82673305410
,
775.5226113240
,
0.00000005064
,
4.66284525271
,
1577.3435424478
};
private
static
final
double
E13
[]
=
{
0.00000289226
,
5.84384198723
,
6283.0758499914
,
0.00000034955
,
0.00000000000
,
0.0000000000
,
0.00000016819
,
5.48766912348
,
12566.1516999828
};
private
static
final
double
E14
[]
=
{
0.00000114084
,
3.14159265359
,
0.0000000000
,
0.00000007717
,
4.13446589358
,
6283.0758499914
,
0.00000000765
,
3.83803776214
,
12566.1516999828
};
private
static
final
double
E15
[]
=
{
0.00000000878
,
3.14159265359
,
0.0000000000
};
private
static
final
double
E20
[]
=
{
//黄纬周期项
0.00000279620
,
3.19870156017
,
84334.6615813083
,
0.00000101643
,
5.42248619256
,
5507.5532386674
,
0.00000080445
,
3.88013204458
,
5223.6939198022
,
0.00000043806
,
3.70444689758
,
2352.8661537718
,
0.00000031933
,
4.00026369781
,
1577.3435424478
,
0.00000022724
,
3.98473831560
,
1047.7473117547
,
0.00000016392
,
3.56456119782
,
5856.4776591154
,
0.00000018141
,
4.98367470263
,
6283.0758499914
,
0.00000014443
,
3.70275614914
,
9437.7629348870
,
0.00000014304
,
3.41117857525
,
10213.2855462110
};
private
static
final
double
E21
[]
=
{
0.00000009030
,
3.89729061890
,
5507.5532386674
,
0.00000006177
,
1.73038850355
,
5223.6939198022
};
private
static
final
double
E30
[]
=
{
//距离周期项
1.00013988799
,
0.00000000000
,
0.0000000000
,
0.01670699626
,
3.09846350771
,
6283.0758499914
,
0.00013956023
,
3.05524609620
,
12566.1516999828
,
0.00003083720
,
5.19846674381
,
77713.7714681205
,
0.00001628461
,
1.17387749012
,
5753.3848848968
,
0.00001575568
,
2.84685245825
,
7860.4193924392
,
0.00000924799
,
5.45292234084
,
11506.7697697936
,
0.00000542444
,
4.56409149777
,
3930.2096962196
};
private
static
final
double
E31
[]
=
{
0.00103018608
,
1.10748969588
,
6283.0758499914
,
0.00001721238
,
1.06442301418
,
12566.1516999828
,
0.00000702215
,
3.14159265359
,
0.0000000000
};
private
static
final
double
E32
[]
=
{
0.00004359385
,
5.78455133738
,
6283.0758499914
};
private
static
final
double
E33
[]
=
{
0.00000144595
,
4.27319435148
,
6283.0758499914
};
//月球运动参数
private
static
final
double
M10
[]
=
{
22639.5858800
,
2.3555545723
,
8328.6914247251
,
1.5231275
E
-
04
,
2.5041111
E
-
07
,
-
1.1863391
E
-
09
,
4586.4383203
,
8.0413790709
,
7214.0628654588
,
-
2.1850087
E
-
04
,
-
1.8646419
E
-
07
,
8.7760973
E
-
10
,
2369.9139357
,
10.3969336431
,
15542.7542901840
,
-
6.6188121
E
-
05
,
6.3946925
E
-
08
,
-
3.0872935
E
-
10
,
769.0257187
,
4.7111091445
,
16657.3828494503
,
3.0462550
E
-
04
,
5.0082223
E
-
07
,
-
2.3726782
E
-
09
,
-
666.4175399
,
-
0.0431256817
,
628.3019552485
,
-
2.6638815
E
-
06
,
6.1639211
E
-
10
,
-
5.4439728
E
-
11
,
-
411.5957339
,
3.2558104895
,
16866.9323152810
,
-
1.2804259
E
-
04
,
-
9.8998954
E
-
09
,
4.0433461
E
-
11
,
211.6555524
,
5.6858244986
,
-
1114.6285592663
,
-
3.7081362
E
-
04
,
-
4.3687530
E
-
07
,
2.0639488
E
-
09
,
205.4359530
,
8.0845047526
,
6585.7609102104
,
-
2.1583699
E
-
04
,
-
1.8708058
E
-
07
,
9.3204945
E
-
10
,
191.9561973
,
12.7524882154
,
23871.4457149091
,
8.6124629
E
-
05
,
3.1435804
E
-
07
,
-
1.4950684
E
-
09
,
164.7286185
,
10.4400593249
,
14914.4523349355
,
-
6.3524240
E
-
05
,
6.3330532
E
-
08
,
-
2.5428962
E
-
10
,
-
147.3213842
,
-
2.3986802540
,
-
7700.3894694766
,
-
1.5497663
E
-
04
,
-
2.4979472
E
-
07
,
1.1318993
E
-
09
,
-
124.9881185
,
5.1984668216
,
7771.3771450920
,
-
3.3094061
E
-
05
,
3.1973462
E
-
08
,
-
1.5436468
E
-
10
,
-
109.3803637
,
2.3124288905
,
8956.9933799736
,
1.4964887
E
-
04
,
2.5102751
E
-
07
,
-
1.2407788
E
-
09
,
55.1770578
,
7.1411231536
,
-
1324.1780250970
,
6.1854469
E
-
05
,
7.3846820
E
-
08
,
-
3.4916281
E
-
10
,
-
45.0996092
,
5.6113650618
,
25195.6237400061
,
2.4270161
E
-
05
,
2.4051122
E
-
07
,
-
1.1459056
E
-
09
,
39.5333010
,
-
0.9002559173
,
-
8538.2408905558
,
2.8035534
E
-
04
,
2.6031101
E
-
07
,
-
1.2267725
E
-
09
,
38.4298346
,
18.4383127140
,
22756.8171556428
,
-
2.8468899
E
-
04
,
-
1.2251727
E
-
07
,
5.6888037
E
-
10
,
36.1238141
,
7.0666637168
,
24986.0742741754
,
4.5693825
E
-
04
,
7.5123334
E
-
07
,
-
3.5590172
E
-
09
,
30.7725751
,
16.0827581417
,
14428.1257309177
,
-
4.3700174
E
-
04
,
-
3.7292838
E
-
07
,
1.7552195
E
-
09
,
-
28.3971008
,
7.9982533891
,
7842.3648207073
,
-
2.2116475
E
-
04
,
-
1.8584780
E
-
07
,
8.2317000
E
-
10
,
-
24.3582283
,
10.3538079614
,
16171.0562454324
,
-
6.8852003
E
-
05
,
6.4563317
E
-
08
,
-
3.6316908
E
-
10
,
-
18.5847068
,
2.8429122493
,
-
557.3142796331
,
-
1.8540681
E
-
04
,
-
2.1843765
E
-
07
,
1.0319744
E
-
09
,
17.9544674
,
5.1553411398
,
8399.6791003405
,
-
3.5757942
E
-
05
,
3.2589854
E
-
08
,
-
2.0880440
E
-
10
,
14.5302779
,
12.7956138971
,
23243.1437596606
,
8.8788511
E
-
05
,
3.1374165
E
-
07
,
-
1.4406287
E
-
09
,
14.3796974
,
15.1080427876
,
32200.1371396342
,
2.3843738
E
-
04
,
5.6476915
E
-
07
,
-
2.6814075
E
-
09
,
14.2514576
,
-
24.0810366320
,
-
2.3011998397
,
1.5231275
E
-
04
,
2.5041111
E
-
07
,
-
1.1863391
E
-
09
,
13.8990596
,
20.7938672862
,
31085.5085803679
,
-
1.3237624
E
-
04
,
1.2789385
E
-
07
,
-
6.1745870
E
-
10
,
13.1940636
,
3.3302699264
,
-
9443.3199839914
,
-
5.2312637
E
-
04
,
-
6.8728642
E
-
07
,
3.2502879
E
-
09
,
-
9.6790568
,
-
4.7542348263
,
-
16029.0808942018
,
-
3.0728938
E
-
04
,
-
5.0020584
E
-
07
,
2.3182384
E
-
09
,
-
9.3658635
,
11.2971895604
,
24080.9951807398
,
-
3.4654346
E
-
04
,
-
1.9636409
E
-
07
,
9.1804319
E
-
10
,
8.6055318
,
5.7289501804
,
-
1742.9305145148
,
-
3.6814974
E
-
04
,
-
4.3749170
E
-
07
,
2.1183885
E
-
09
,
-
8.4530982
,
7.5540213938
,
16100.0685698171
,
1.1921869
E
-
04
,
2.8238458
E
-
07
,
-
1.3407038
E
-
09
,
8.0501724
,
10.4831850066
,
14286.1503796870
,
-
6.0860358
E
-
05
,
6.2714140
E
-
08
,
-
1.9984990
E
-
10
,
-
7.6301553
,
4.6679834628
,
17285.6848046987
,
3.0196162
E
-
04
,
5.0143862
E
-
07
,
-
2.4271179
E
-
09
,
-
7.4474952
,
-
0.0862513635
,
1256.6039104970
,
-
5.3277630
E
-
06
,
1.2327842
E
-
09
,
-
1.0887946
E
-
10
,
7.3712011
,
8.1276304344
,
5957.4589549619
,
-
2.1317311
E
-
04
,
-
1.8769697
E
-
07
,
9.8648918
E
-
10
,
7.0629900
,
0.9591375719
,
33.7570471374
,
-
3.0829302
E
-
05
,
-
3.6967043
E
-
08
,
1.7385419
E
-
10
,
-
6.3831491
,
9.4966777258
,
7004.5133996281
,
2.1416722
E
-
04
,
3.2425793
E
-
07
,
-
1.5355019
E
-
09
,
-
5.7416071
,
13.6527441326
,
32409.6866054649
,
-
1.9423071
E
-
04
,
5.4047029
E
-
08
,
-
2.6829589
E
-
10
,
4.3740095
,
18.4814383957
,
22128.5152003943
,
-
2.8202511
E
-
04
,
-
1.2313366
E
-
07
,
6.2332010
E
-
10
,
-
3.9976134
,
7.9669196340
,
33524.3151647312
,
1.7658291
E
-
04
,
4.9092233
E
-
07
,
-
2.3322447
E
-
09
,
-
3.2096876
,
13.2398458924
,
14985.4400105508
,
-
2.5159493
E
-
04
,
-
1.5449073
E
-
07
,
7.2324505
E
-
10
,
-
2.9145404
,
12.7093625336
,
24499.7476701576
,
8.3460748
E
-
05
,
3.1497443
E
-
07
,
-
1.5495082
E
-
09
,
2.7318890
,
16.1258838235
,
13799.8237756692
,
-
4.3433786
E
-
04
,
-
3.7354477
E
-
07
,
1.8096592
E
-
09
,
-
2.5679459
,
-
2.4418059357
,
-
7072.0875142282
,
-
1.5764051
E
-
04
,
-
2.4917833
E
-
07
,
1.0774596
E
-
09
,
-
2.5211990
,
7.9551277074
,
8470.6667759558
,
-
2.2382863
E
-
04
,
-
1.8523141
E
-
07
,
7.6873027
E
-
10
,
2.4888871
,
5.6426988169
,
-
486.3266040178
,
-
3.7347750
E
-
04
,
-
4.3625891
E
-
07
,
2.0095091
E
-
09
,
2.1460741
,
7.1842488353
,
-
1952.4799803455
,
6.4518350
E
-
05
,
7.3230428
E
-
08
,
-
2.9472308
E
-
10
,
1.9777270
,
23.1494218585
,
39414.2000050930
,
1.9936508
E
-
05
,
3.7830496
E
-
07
,
-
1.8037978
E
-
09
,
1.9336825
,
9.4222182890
,
33314.7656989005
,
6.0925100
E
-
04
,
1.0016445
E
-
06
,
-
4.7453563
E
-
09
,
1.8707647
,
20.8369929680
,
30457.2066251194
,
-
1.2971236
E
-
04
,
1.2727746
E
-
07
,
-
5.6301898
E
-
10
,
-
1.7529659
,
0.4873576771
,
-
8886.0057043583
,
-
3.3771956
E
-
04
,
-
4.6884877
E
-
07
,
2.2183135
E
-
09
,
-
1.4371624
,
7.0979974718
,
-
695.8760698485
,
5.9190587
E
-
05
,
7.4463212
E
-
08
,
-
4.0360254
E
-
10
,
-
1.3725701
,
1.4552986550
,
-
209.5494658307
,
4.3266809
E
-
04
,
5.1072212
E
-
07
,
-
2.4131116
E
-
09
,
1.2618162
,
7.5108957121
,
16728.3705250656
,
1.1655481
E
-
04
,
2.8300097
E
-
07
,
-
1.3951435
E
-
09
};
private
static
final
double
M11
[]
=
{
1.6768000
,
-
0.0431256817
,
628.3019552485
,
-
2.6638815
E
-
06
,
6.1639211
E
-
10
,
-
5.4439728
E
-
11
,
0.5164200
,
11.2260974062
,
6585.7609102104
,
-
2.1583699
E
-
04
,
-
1.8708058
E
-
07
,
9.3204945
E
-
10
,
0.4138300
,
13.5816519784
,
14914.4523349355
,
-
6.3524240
E
-
05
,
6.3330532
E
-
08
,
-
2.5428962
E
-
10
,
0.3711500
,
5.5402729076
,
7700.3894694766
,
1.5497663
E
-
04
,
2.4979472
E
-
07
,
-
1.1318993
E
-
09
,
0.2756000
,
2.3124288905
,
8956.9933799736
,
1.4964887
E
-
04
,
2.5102751
E
-
07
,
-
1.2407788
E
-
09
,
0.2459863
,
-
25.6198212459
,
-
2.3011998397
,
1.5231275
E
-
04
,
2.5041111
E
-
07
,
-
1.1863391
E
-
09
,
0.0711800
,
7.9982533891
,
7842.3648207073
,
-
2.2116475
E
-
04
,
-
1.8584780
E
-
07
,
8.2317000
E
-
10
,
0.0612800
,
10.3538079614
,
16171.0562454324
,
-
6.8852003
E
-
05
,
6.4563317
E
-
08
,
-
3.6316908
E
-
10
};
private
static
final
double
M12
[]
=
{
0.0048700
,
-
0.0431256817
,
628.3019552485
,
-
2.6638815
E
-
06
,
6.1639211
E
-
10
,
-
5.4439728
E
-
11
,
0.0022800
,
-
27.1705318325
,
-
2.3011998397
,
1.5231275
E
-
04
,
2.5041111
E
-
07
,
-
1.1863391
E
-
09
,
0.0015000
,
11.2260974062
,
6585.7609102104
,
-
2.1583699
E
-
04
,
-
1.8708058
E
-
07
,
9.3204945
E
-
10
};
private
static
final
double
M20
[]
=
{
18461.2400600
,
1.6279052448
,
8433.4661576405
,
-
6.4021295
E
-
05
,
-
4.9499477
E
-
09
,
2.0216731
E
-
11
,
1010.1671484
,
3.9834598170
,
16762.1575823656
,
8.8291456
E
-
05
,
2.4546117
E
-
07
,
-
1.1661223
E
-
09
,
999.6936555
,
0.7276493275
,
-
104.7747329154
,
2.1633405
E
-
04
,
2.5536106
E
-
07
,
-
1.2065558
E
-
09
,
623.6524746
,
8.7690283983
,
7109.2881325435
,
-
2.1668263
E
-
06
,
6.8896872
E
-
08
,
-
3.2894608
E
-
10
,
199.4837596
,
9.6692843156
,
15647.5290230993
,
-
2.8252217
E
-
04
,
-
1.9141414
E
-
07
,
8.9782646
E
-
10
,
166.5741153
,
6.4134738261
,
-
1219.4032921817
,
-
1.5447958
E
-
04
,
-
1.8151424
E
-
07
,
8.5739300
E
-
10
,
117.2606951
,
12.0248388879
,
23976.2204478244
,
-
1.3020942
E
-
04
,
5.8996977
E
-
08
,
-
2.8851262
E
-
10
,
61.9119504
,
6.3390143893
,
25090.8490070907
,
2.4060421
E
-
04
,
4.9587228
E
-
07
,
-
2.3524614
E
-
09
,
33.3572027
,
11.1245829706
,
15437.9795572686
,
1.5014592
E
-
04
,
3.1930799
E
-
07
,
-
1.5152852
E
-
09
,
31.7596709
,
3.0832038997
,
8223.9166918098
,
3.6864680
E
-
04
,
5.0577218
E
-
07
,
-
2.3928949
E
-
09
,
29.5766003
,
8.8121540801
,
6480.9861772950
,
4.9705523
E
-
07
,
6.8280480
E
-
08
,
-
2.7450635
E
-
10
,
15.5662654
,
4.0579192538
,
-
9548.0947169068
,
-
3.0679233
E
-
04
,
-
4.3192536
E
-
07
,
2.0437321
E
-
09
,
15.1215543
,
14.3803934601
,
32304.9118725496
,
2.2103334
E
-
05
,
3.0940809
E
-
07
,
-
1.4748517
E
-
09
,
-
12.0941511
,
8.7259027166
,
7737.5900877920
,
-
4.8307078
E
-
06
,
6.9513264
E
-
08
,
-
3.8338581
E
-
10
,
8.8681426
,
9.7124099974
,
15019.2270678508
,
-
2.7985829
E
-
04
,
-
1.9203053
E
-
07
,
9.5226618
E
-
10
,
8.0450400
,
0.6687636586
,
8399.7091105030
,
-
3.3191993
E
-
05
,
3.2017096
E
-
08
,
-
1.5363746
E
-
10
,
7.9585542
,
12.0679645696
,
23347.9184925760
,
-
1.2754553
E
-
04
,
5.8380585
E
-
08
,
-
2.3407289
E
-
10
,
7.4345550
,
6.4565995078
,
-
1847.7052474301
,
-
1.5181570
E
-
04
,
-
1.8213063
E
-
07
,
9.1183272
E
-
10
,
-
6.7314363
,
-
4.0265854988
,
-
16133.8556271171
,
-
9.0955337
E
-
05
,
-
2.4484477
E
-
07
,
1.1116826
E
-
09
,
6.5795750
,
16.8104074692
,
14323.3509980023
,
-
2.2066770
E
-
04
,
-
1.1756732
E
-
07
,
5.4866364
E
-
10
,
-
6.4600721
,
1.5847795630
,
9061.7681128890
,
-
6.6685176
E
-
05
,
-
4.3335556
E
-
09
,
-
3.4222998
E
-
11
,
-
6.2964773
,
4.8837157343
,
25300.3984729215
,
-
1.9206388
E
-
04
,
-
1.4849843
E
-
08
,
6.0650192
E
-
11
,
-
5.6323538
,
-
0.7707750092
,
733.0766881638
,
-
2.1899793
E
-
04
,
-
2.5474467
E
-
07
,
1.1521161
E
-
09
,
-
5.3683961
,
6.8263720663
,
16204.8433027325
,
-
9.7115356
E
-
05
,
2.7023515
E
-
08
,
-
1.3414795
E
-
10
,
-
5.3112784
,
3.9403341353
,
17390.4595376141
,
8.5627574
E
-
05
,
2.4607756
E
-
07
,
-
1.2205621
E
-
09
,
-
5.0759179
,
0.6845236457
,
523.5272223331
,
2.1367016
E
-
04
,
2.5597745
E
-
07
,
-
1.2609955
E
-
09
,
-
4.8396143
,
-
1.6710309265
,
-
7805.1642023920
,
6.1357413
E
-
05
,
5.5663398
E
-
09
,
-
7.4656459
E
-
11
,
-
4.8057401
,
3.5705615768
,
-
662.0890125485
,
3.0927234
E
-
05
,
3.6923410
E
-
08
,
-
1.7458141
E
-
10
,
3.9840545
,
8.6945689615
,
33419.5404318159
,
3.9291696
E
-
04
,
7.4628340
E
-
07
,
-
3.5388005
E
-
09
,
3.6744619
,
19.1659620415
,
22652.0424227274
,
-
6.8354947
E
-
05
,
1.3284380
E
-
07
,
-
6.3767543
E
-
10
,
2.9984815
,
20.0662179587
,
31190.2833132833
,
-
3.4871029
E
-
04
,
-
1.2746721
E
-
07
,
5.8909710
E
-
10
,
2.7986413
,
-
2.5281611620
,
-
16971.7070481963
,
3.4437664
E
-
04
,
2.6526096
E
-
07
,
-
1.2469893
E
-
09
,
2.4138774
,
17.7106633865
,
22861.5918885581
,
-
5.0102304
E
-
04
,
-
3.7787833
E
-
07
,
1.7754362
E
-
09
,
2.1863132
,
5.5132179088
,
-
9757.6441827375
,
1.2587576
E
-
04
,
7.8796768
E
-
08
,
-
3.6937954
E
-
10
,
2.1461692
,
13.4801375428
,
23766.6709819937
,
3.0245868
E
-
04
,
5.6971910
E
-
07
,
-
2.7016242
E
-
09
,
1.7659832
,
11.1677086523
,
14809.6776020201
,
1.5280981
E
-
04
,
3.1869159
E
-
07
,
-
1.4608454
E
-
09
,
-
1.6244212
,
7.3137297434
,
7318.8375983742
,
-
4.3483492
E
-
04
,
-
4.4182525
E
-
07
,
2.0841655
E
-
09
,
1.5813036
,
5.4387584720
,
16552.6081165349
,
5.2095955
E
-
04
,
7.5618329
E
-
07
,
-
3.5792340
E
-
09
,
1.5197528
,
16.7359480324
,
40633.6032972747
,
1.7441609
E
-
04
,
5.5981921
E
-
07
,
-
2.6611908
E
-
09
,
1.5156341
,
1.7023646816
,
-
17876.7861416319
,
-
4.5910508
E
-
04
,
-
6.8233647
E
-
07
,
3.2300712
E
-
09
,
1.5102092
,
5.4977296450
,
8399.6847301375
,
-
3.3094061
E
-
05
,
3.1973462
E
-
08
,
-
1.5436468
E
-
10
,
-
1.3178223
,
9.6261586339
,
16275.8309783478
,
-
2.8518605
E
-
04
,
-
1.9079775
E
-
07
,
8.4338673
E
-
10
,
-
1.2642739
,
11.9817132061
,
24604.5224030729
,
-
1.3287330
E
-
04
,
5.9613369
E
-
08
,
-
3.4295235
E
-
10
,
1.1918723
,
22.4217725310
,
39518.9747380084
,
-
1.9639754
E
-
04
,
1.2294390
E
-
07
,
-
5.9724197
E
-
10
,
1.1346110
,
14.4235191419
,
31676.6099173011
,
2.4767216
E
-
05
,
3.0879170
E
-
07
,
-
1.4204120
E
-
09
,
1.0857810
,
8.8552797618
,
5852.6842220465
,
3.1609367
E
-
06
,
6.7664088
E
-
08
,
-
2.2006663
E
-
10
,
-
1.0193852
,
7.2392703065
,
33629.0898976466
,
-
3.9751134
E
-
05
,
2.3556127
E
-
07
,
-
1.1256889
E
-
09
,
-
0.8227141
,
11.0814572888
,
16066.2815125171
,
1.4748204
E
-
04
,
3.1992438
E
-
07
,
-
1.5697249
E
-
09
,
0.8042238
,
3.5274358950
,
-
33.7870573000
,
2.8263353
E
-
05
,
3.7539802
E
-
08
,
-
2.2902113
E
-
10
,
0.8025939
,
6.7832463846
,
16833.1452579809
,
-
9.9779237
E
-
05
,
2.7639907
E
-
08
,
-
1.8858767
E
-
10
,
-
0.7931866
,
-
6.3821400710
,
-
24462.5470518423
,
-
2.4326809
E
-
04
,
-
4.9525589
E
-
07
,
2.2980217
E
-
09
,
-
0.7910153
,
6.3703481443
,
-
591.1013369332
,
-
1.5714346
E
-
04
,
-
1.8089785
E
-
07
,
8.0295327
E
-
10
,
-
0.6674056
,
9.1819266386
,
24533.5347274576
,
5.5197395
E
-
05
,
2.7743463
E
-
07
,
-
1.3204870
E
-
09
,
0.6502226
,
4.1010449356
,
-
10176.3966721553
,
-
3.0412845
E
-
04
,
-
4.3254175
E
-
07
,
2.0981718
E
-
09
,
-
0.6388131
,
6.2958887075
,
25719.1509623392
,
2.3794032
E
-
04
,
4.9648867
E
-
07
,
-
2.4069012
E
-
09
};
private
static
final
double
M21
[]
=
{
0.0743000
,
11.9537467337
,
6480.9861772950
,
4.9705523
E
-
07
,
6.8280480
E
-
08
,
-
2.7450635
E
-
10
,
0.0304300
,
8.7259027166
,
7737.5900877920
,
-
4.8307078
E
-
06
,
6.9513264
E
-
08
,
-
3.8338581
E
-
10
,
0.0222900
,
12.8540026510
,
15019.2270678508
,
-
2.7985829
E
-
04
,
-
1.9203053
E
-
07
,
9.5226618
E
-
10
,
0.0199900
,
15.2095572232
,
23347.9184925760
,
-
1.2754553
E
-
04
,
5.8380585
E
-
08
,
-
2.3407289
E
-
10
,
0.0186900
,
9.5981921614
,
-
1847.7052474301
,
-
1.5181570
E
-
04
,
-
1.8213063
E
-
07
,
9.1183272
E
-
10
,
0.0169600
,
7.1681781524
,
16133.8556271171
,
9.0955337
E
-
05
,
2.4484477
E
-
07
,
-
1.1116826
E
-
09
,
0.0162300
,
1.5847795630
,
9061.7681128890
,
-
6.6685176
E
-
05
,
-
4.3335556
E
-
09
,
-
3.4222998
E
-
11
,
0.0141900
,
-
0.7707750092
,
733.0766881638
,
-
2.1899793
E
-
04
,
-
2.5474467
E
-
07
,
1.1521161
E
-
09
};
private
static
final
double
M30
[]
=
{
385000.5290396
,
1.5707963268
,
0.0000000000
,
0.0000000
E
+
00
,
0.0000000
E
+
00
,
0.0000000
E
+
00
,
-
20905.3551378
,
3.9263508990
,
8328.6914247251
,
1.5231275
E
-
04
,
2.5041111
E
-
07
,
-
1.1863391
E
-
09
,
-
3699.1109330
,
9.6121753977
,
7214.0628654588
,
-
2.1850087
E
-
04
,
-
1.8646419
E
-
07
,
8.7760973
E
-
10
,
-
2955.9675626
,
11.9677299699
,
15542.7542901840
,
-
6.6188121
E
-
05
,
6.3946925
E
-
08
,
-
3.0872935
E
-
10
,
-
569.9251264
,
6.2819054713
,
16657.3828494503
,
3.0462550
E
-
04
,
5.0082223
E
-
07
,
-
2.3726782
E
-
09
,
246.1584797
,
7.2566208254
,
-
1114.6285592663
,
-
3.7081362
E
-
04
,
-
4.3687530
E
-
07
,
2.0639488
E
-
09
,
-
204.5861179
,
12.0108556517
,
14914.4523349355
,
-
6.3524240
E
-
05
,
6.3330532
E
-
08
,
-
2.5428962
E
-
10
,
-
170.7330791
,
14.3232845422
,
23871.4457149091
,
8.6124629
E
-
05
,
3.1435804
E
-
07
,
-
1.4950684
E
-
09
,
-
152.1378118
,
9.6553010794
,
6585.7609102104
,
-
2.1583699
E
-
04
,
-
1.8708058
E
-
07
,
9.3204945
E
-
10
,
-
129.6202242
,
-
0.8278839272
,
-
7700.3894694766
,
-
1.5497663
E
-
04
,
-
2.4979472
E
-
07
,
1.1318993
E
-
09
,
108.7427014
,
6.7692631483
,
7771.3771450920
,
-
3.3094061
E
-
05
,
3.1973462
E
-
08
,
-
1.5436468
E
-
10
,
104.7552944
,
3.8832252173
,
8956.9933799736
,
1.4964887
E
-
04
,
2.5102751
E
-
07
,
-
1.2407788
E
-
09
,
79.6605685
,
0.6705404095
,
-
8538.2408905558
,
2.8035534
E
-
04
,
2.6031101
E
-
07
,
-
1.2267725
E
-
09
,
48.8883284
,
1.5276706450
,
628.3019552485
,
-
2.6638815
E
-
06
,
6.1639211
E
-
10
,
-
5.4439728
E
-
11
,
-
34.7825237
,
20.0091090408
,
22756.8171556428
,
-
2.8468899
E
-
04
,
-
1.2251727
E
-
07
,
5.6888037
E
-
10
,
30.8238599
,
11.9246042882
,
16171.0562454324
,
-
6.8852003
E
-
05
,
6.4563317
E
-
08
,
-
3.6316908
E
-
10
,
24.2084985
,
9.5690497159
,
7842.3648207073
,
-
2.2116475
E
-
04
,
-
1.8584780
E
-
07
,
8.2317000
E
-
10
,
-
23.2104305
,
8.6374600436
,
24986.0742741754
,
4.5693825
E
-
04
,
7.5123334
E
-
07
,
-
3.5590172
E
-
09
,
-
21.6363439
,
17.6535544685
,
14428.1257309177
,
-
4.3700174
E
-
04
,
-
3.7292838
E
-
07
,
1.7552195
E
-
09
,
-
16.6747239
,
6.7261374666
,
8399.6791003405
,
-
3.5757942
E
-
05
,
3.2589854
E
-
08
,
-
2.0880440
E
-
10
,
14.4026890
,
4.9010662531
,
-
9443.3199839914
,
-
5.2312637
E
-
04
,
-
6.8728642
E
-
07
,
3.2502879
E
-
09
,
-
12.8314035
,
14.3664102239
,
23243.1437596606
,
8.8788511
E
-
05
,
3.1374165
E
-
07
,
-
1.4406287
E
-
09
,
-
11.6499478
,
22.3646636130
,
31085.5085803679
,
-
1.3237624
E
-
04
,
1.2789385
E
-
07
,
-
6.1745870
E
-
10
,
-
10.4447578
,
16.6788391144
,
32200.1371396342
,
2.3843738
E
-
04
,
5.6476915
E
-
07
,
-
2.6814075
E
-
09
,
10.3211071
,
8.7119194804
,
-
1324.1780250970
,
6.1854469
E
-
05
,
7.3846820
E
-
08
,
-
3.4916281
E
-
10
,
10.0562033
,
7.2997465071
,
-
1742.9305145148
,
-
3.6814974
E
-
04
,
-
4.3749170
E
-
07
,
2.1183885
E
-
09
,
-
9.8844667
,
12.0539813334
,
14286.1503796870
,
-
6.0860358
E
-
05
,
6.2714140
E
-
08
,
-
1.9984990
E
-
10
,
8.7515625
,
6.3563649081
,
-
9652.8694498221
,
-
9.0458282
E
-
05
,
-
1.7656429
E
-
07
,
8.3717626
E
-
10
,
-
8.3791067
,
4.4137085761
,
-
557.3142796331
,
-
1.8540681
E
-
04
,
-
2.1843765
E
-
07
,
1.0319744
E
-
09
,
-
7.0026961
,
-
3.1834384995
,
-
16029.0808942018
,
-
3.0728938
E
-
04
,
-
5.0020584
E
-
07
,
2.3182384
E
-
09
,
6.3220032
,
9.1248177206
,
16100.0685698171
,
1.1921869
E
-
04
,
2.8238458
E
-
07
,
-
1.3407038
E
-
09
,
5.7508579
,
6.2387797896
,
17285.6848046987
,
3.0196162
E
-
04
,
5.0143862
E
-
07
,
-
2.4271179
E
-
09
,
-
4.9501349
,
9.6984267611
,
5957.4589549619
,
-
2.1317311
E
-
04
,
-
1.8769697
E
-
07
,
9.8648918
E
-
10
,
-
4.4211770
,
3.0260949818
,
-
209.5494658307
,
4.3266809
E
-
04
,
5.1072212
E
-
07
,
-
2.4131116
E
-
09
,
4.1311145
,
11.0674740526
,
7004.5133996281
,
2.1416722
E
-
04
,
3.2425793
E
-
07
,
-
1.5355019
E
-
09
,
-
3.9579827
,
20.0522347225
,
22128.5152003943
,
-
2.8202511
E
-
04
,
-
1.2313366
E
-
07
,
6.2332010
E
-
10
,
3.2582371
,
14.8106422192
,
14985.4400105508
,
-
2.5159493
E
-
04
,
-
1.5449073
E
-
07
,
7.2324505
E
-
10
,
-
3.1483020
,
4.8266068163
,
16866.9323152810
,
-
1.2804259
E
-
04
,
-
9.8998954
E
-
09
,
4.0433461
E
-
11
,
2.6164092
,
14.2801588604
,
24499.7476701576
,
8.3460748
E
-
05
,
3.1497443
E
-
07
,
-
1.5495082
E
-
09
,
2.3536310
,
9.5259240342
,
8470.6667759558
,
-
2.2382863
E
-
04
,
-
1.8523141
E
-
07
,
7.6873027
E
-
10
,
-
2.1171283
,
-
0.8710096090
,
-
7072.0875142282
,
-
1.5764051
E
-
04
,
-
2.4917833
E
-
07
,
1.0774596
E
-
09
,
-
1.8970368
,
17.6966801503
,
13799.8237756692
,
-
4.3433786
E
-
04
,
-
3.7354477
E
-
07
,
1.8096592
E
-
09
,
-
1.7385258
,
2.0581540038
,
-
8886.0057043583
,
-
3.3771956
E
-
04
,
-
4.6884877
E
-
07
,
2.2183135
E
-
09
,
-
1.5713944
,
22.4077892948
,
30457.2066251194
,
-
1.2971236
E
-
04
,
1.2727746
E
-
07
,
-
5.6301898
E
-
10
,
-
1.4225541
,
24.7202181853
,
39414.2000050930
,
1.9936508
E
-
05
,
3.7830496
E
-
07
,
-
1.8037978
E
-
09
,
-
1.4189284
,
17.1661967915
,
23314.1314352759
,
-
9.9282182
E
-
05
,
9.5920387
E
-
08
,
-
4.6309403
E
-
10
,
1.1655364
,
3.8400995356
,
9585.2953352221
,
1.4698499
E
-
04
,
2.5164390
E
-
07
,
-
1.2952185
E
-
09
,
-
1.1169371
,
10.9930146158
,
33314.7656989005
,
6.0925100
E
-
04
,
1.0016445
E
-
06
,
-
4.7453563
E
-
09
,
1.0656723
,
1.4845449633
,
1256.6039104970
,
-
5.3277630
E
-
06
,
1.2327842
E
-
09
,
-
1.0887946
E
-
10
,
1.0586190
,
11.9220903668
,
8364.7398411275
,
-
2.1850087
E
-
04
,
-
1.8646419
E
-
07
,
8.7760973
E
-
10
,
-
0.9333176
,
9.0816920389
,
16728.3705250656
,
1.1655481
E
-
04
,
2.8300097
E
-
07
,
-
1.3951435
E
-
09
,
0.8624328
,
12.4550876470
,
6656.7485858257
,
-
4.0390768
E
-
04
,
-
4.0490184
E
-
07
,
1.9095841
E
-
09
,
0.8512404
,
4.3705828944
,
70.9876756153
,
-
1.8807069
E
-
04
,
-
2.1782126
E
-
07
,
9.7753467
E
-
10
,
-
0.8488018
,
16.7219647962
,
31571.8351843857
,
2.4110126
E
-
04
,
5.6415276
E
-
07
,
-
2.6269678
E
-
09
,
-
0.7956264
,
3.5134526588
,
-
9095.5551701890
,
9.4948529
E
-
05
,
4.1873358
E
-
08
,
-
1.9479814
E
-
10
};
private
static
final
double
M31
[]
=
{
0.5139500
,
12.0108556517
,
14914.4523349355
,
-
6.3524240
E
-
05
,
6.3330532
E
-
08
,
-
2.5428962
E
-
10
,
0.3824500
,
9.6553010794
,
6585.7609102104
,
-
2.1583699
E
-
04
,
-
1.8708058
E
-
07
,
9.3204945
E
-
10
,
0.3265400
,
3.9694765808
,
7700.3894694766
,
1.5497663
E
-
04
,
2.4979472
E
-
07
,
-
1.1318993
E
-
09
,
0.2639600
,
0.7416325637
,
8956.9933799736
,
1.4964887
E
-
04
,
2.5102751
E
-
07
,
-
1.2407788
E
-
09
,
0.1230200
,
-
1.6139220085
,
628.3019552485
,
-
2.6638815
E
-
06
,
6.1639211
E
-
10
,
-
5.4439728
E
-
11
,
0.0775400
,
8.7830116346
,
16171.0562454324
,
-
6.8852003
E
-
05
,
6.4563317
E
-
08
,
-
3.6316908
E
-
10
,
0.0606800
,
6.4274570623
,
7842.3648207073
,
-
2.2116475
E
-
04
,
-
1.8584780
E
-
07
,
8.2317000
E
-
10
,
0.0497000
,
12.0539813334
,
14286.1503796870
,
-
6.0860358
E
-
05
,
6.2714140
E
-
08
,
-
1.9984990
E
-
10
};
private
static
final
double
M1n
[]
=
{
3.81034392032
,
8.39968473021
E
+
03
,
-
3.31919929753
E
-
05
,
//月球平黄经系数
3.20170955005
E
-
08
,
-
1.53637455544
E
-
10
};
private
static
double
EnnT
=
0
;
// 调用Enn前先设置EnnT时间变量
/**
* 计算E10,E11,E20等,即:某一组周期项或泊松项算出,计算前先设置EnnT时间
*
* @param F F
* @return 计算E10, E11, E20等
*/
private
static
double
Enn
(
double
[]
F
)
{
double
v
=
0
;
for
(
int
i
=
0
;
i
<
F
.
length
;
i
+=
3
)
v
+=
F
[
i
]
*
Math
.
cos
(
F
[
i
+
1
]
+
EnnT
*
F
[
i
+
2
]);
return
v
;
}
/**
* 返回地球位置,日心Date黄道分点坐标
*
* @param jd jd
* @return 返回地球位置, 日心Date黄道分点坐标
*/
private
static
double
[]
earCal
(
double
jd
)
{
EnnT
=
jd
/
365250
;
double
llr
[]
=
new
double
[
3
];
double
t1
=
EnnT
,
t2
=
t1
*
t1
,
t3
=
t2
*
t1
,
t4
=
t3
*
t1
,
t5
=
t4
*
t1
;
llr
[
0
]
=
Enn
(
E10
)
+
Enn
(
E11
)
*
t1
+
Enn
(
E12
)
*
t2
+
Enn
(
E13
)
*
t3
+
Enn
(
E14
)
*
t4
+
Enn
(
E15
)
*
t5
;
llr
[
1
]
=
Enn
(
E20
)
+
Enn
(
E21
)
*
t1
;
llr
[
2
]
=
Enn
(
E30
)
+
Enn
(
E31
)
*
t1
+
Enn
(
E32
)
*
t2
+
Enn
(
E33
)
*
t3
;
llr
[
0
]
=
rad2mrad
(
llr
[
0
]);
return
llr
;
}
// ==================月位置计算===================
private
static
double
MnnT
=
0
;
// 调用Mnn前先设置MnnT时间变量
/**
* 计算M10,M11,M20等,计算前先设置MnnT时间
*
* @param F F
* @return 计算M10, M11, M20等, 计算前先设置MnnT时间
*/
private
static
double
Mnn
(
double
[]
F
)
{
double
v
=
0
,
t1
=
MnnT
,
t2
=
t1
*
t1
,
t3
=
t2
*
t1
,
t4
=
t3
*
t1
;
for
(
int
i
=
0
;
i
<
F
.
length
;
i
+=
6
)
v
+=
F
[
i
]
*
Math
.
sin
(
F
[
i
+
1
]
+
t1
*
F
[
i
+
2
]
+
t2
*
F
[
i
+
3
]
+
t3
*
F
[
i
+
4
]
+
t4
*
F
[
i
+
5
]);
return
v
;
}
/**
* 返回月球位置,返回地心Date黄道坐标
*
* @param julian 儒略历
* @return return 地心黄道坐标
*/
private
static
double
[]
moonCoord
(
double
julian
)
{
MnnT
=
julian
/
36525
;
double
t1
=
MnnT
,
t2
=
t1
*
t1
,
t3
=
t2
*
t1
,
t4
=
t3
*
t1
;
double
[]
llr
=
new
double
[
3
];
llr
[
0
]
=
(
Mnn
(
M10
)
+
Mnn
(
M11
)
*
t1
+
Mnn
(
M12
)
*
t2
)
/
SECOND_PER_RAD
;
llr
[
1
]
=
(
Mnn
(
M20
)
+
Mnn
(
M21
)
*
t1
)
/
SECOND_PER_RAD
;
llr
[
2
]
=
(
Mnn
(
M30
)
+
Mnn
(
M31
)
*
t1
)
*
0.999999949827
;
llr
[
0
]
=
llr
[
0
]
+
M1n
[
0
]
+
M1n
[
1
]
*
t1
+
M1n
[
2
]
*
t2
+
M1n
[
3
]
*
t3
+
M1n
[
4
]
*
t4
;
llr
[
0
]
=
rad2mrad
(
llr
[
0
]);
// 地心Date黄道原点坐标(不含岁差)
precession
(
julian
,
llr
);
// 补岁差
return
llr
;
}
/**
* 地心坐标中的日月位置计算
*
* @param lx lx=1时计算t时刻日月角距与jiao的差, lx=0计算t时刻太阳黄经与jiao的差
* @param time time
* @param angle angle
* @return 地心坐标中的日月位置计算
*/
private
static
double
angleDiff
(
int
lx
,
double
time
,
double
angle
)
{
double
[]
sun
=
earCal
(
time
);
// 计算太阳真位置(先算出日心坐标中地球的位置)
sun
[
0
]
+=
Math
.
PI
;
sun
[
1
]
=
-
sun
[
1
];
// 转为地心坐标
addGxc
(
time
,
sun
);
// 补周年光行差
if
(
lx
==
0
)
{
Nutation
d
=
nutation
(
time
);
sun
[
0
]
+=
d
.
Lon
;
// 补黄经章动
return
rad2mrad
(
angle
-
sun
[
0
]);
}
double
[]
moon
=
moonCoord
(
time
);
// 日月角差与章动无关
return
rad2mrad
(
angle
-
(
moon
[
0
]
-
sun
[
0
]));
}
/**
* 已知位置反求时间,对于节气计算,应满足t在t1到t1+360天之间,对于Y年第n个节气(n=0是春分),t1可取值Y*365.2422+n*15.2,
* 对于朔望计算,应满足t在t1到t1+25天之间,在此范围之外,求右边的根
*
* @param t1 J2000起算儒略日数,传入的t1是指定角度对应真时刻t的前一些天
* @param angle 已知角度(jiao)求时间(t)
* @param lx lx=0是太阳黄经达某角度的时刻计算(用于节气计算)
* lx=1是日月角距达某角度的时刻计算(用于定朔望等)
* @return 已知位置反求时间
*/
private
static
double
getTimeFromAngle
(
double
t1
,
double
angle
,
int
lx
)
{
double
t2
=
t1
,
t
=
0
,
v
;
if
(
lx
==
0
)
t2
+=
360
;
// 在t1到t2范围内求解(范气360天范围),结果置于t
else
t2
+=
25
;
angle
*=
Math
.
PI
/
180
;
// 待搜索目标角
// 利用截弦法计算
double
v1
=
angleDiff
(
lx
,
t1
,
angle
);
// v1,v2为t1,t2时对应的黄经
double
v2
=
angleDiff
(
lx
,
t2
,
angle
);
if
(
v1
<
v2
)
v2
-=
2
*
Math
.
PI
;
// 减2pi作用是将周期性角度转为连续角度
double
k
=
1
,
k2
;
// k是截弦的斜率
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
// 快速截弦求根,通常截弦三四次就已达所需精度
k2
=
(
v2
-
v1
)
/
(
t2
-
t1
);
// 算出斜率
if
(
Math
.
abs
(
k2
)
>
1
e
-
15
)
k
=
k2
;
// 差商可能为零,应排除
t
=
t1
-
v1
/
k
;
v
=
angleDiff
(
lx
,
t
,
angle
);
// 直线逼近法求根(直线方程的根)
if
(
v
>
1
)
v
-=
2
*
Math
.
PI
;
// 一次逼近后,v1就已接近0,如果很大,则应减1周
if
(
Math
.
abs
(
v
)
<
1
e
-
8
)
break
;
// 已达精度
t1
=
t2
;
v1
=
v2
;
t2
=
t
;
v2
=
v
;
// 下一次截弦
}
return
t
;
}
/**
* 获得某一年24节气
*
* @param year 年
* @return 24节气
*/
public
static
String
[]
getSolarTerms
(
int
year
)
{
String
[]
solarTerms
=
new
String
[
24
];
String
[]
preOffset
=
getSolarTermsPreOffset
(
year
-
1
);
String
[]
nextOffset
=
getSolarTermsNextOffset
(
year
-
1
);
System
.
arraycopy
(
preOffset
,
0
,
solarTerms
,
0
,
preOffset
.
length
);
System
.
arraycopy
(
nextOffset
,
0
,
solarTerms
,
22
,
nextOffset
.
length
);
double
jd
=
365.2422
*
(
year
-
2000
),
q
;
for
(
int
i
=
0
;
i
<
19
;
i
++)
{
q
=
getTimeFromAngle
(
jd
+
i
*
15.2
,
i
*
15
,
0
);
q
=
q
+
J2000
+
(
double
)
8
/
24
;
// 计算第i个节气(i=0是春分),结果转为北京时
Time
time
=
setFromJulian
(
q
,
true
);
solarTerms
[
i
+
3
]
=
time
.
toString
()
+
SOLAR_TERMS
[
i
];
}
return
solarTerms
;
}
/**
* 要获得2018年24节气需要传入2017年
*
* @param year 要获得2018年24节气需要传入2017年
* @return 返回 立春 雨水 惊蛰
*/
private
static
String
[]
getSolarTermsPreOffset
(
int
year
)
{
String
[]
solarTerms
=
new
String
[
3
];
double
jd
=
365.2422
*
(
year
-
2000
),
q
;
for
(
int
i
=
21
;
i
<
24
;
i
++)
{
q
=
getTimeFromAngle
(
jd
+
i
*
15.2
,
i
*
15
,
0
);
q
=
q
+
J2000
+
(
double
)
8
/
24
;
// 计算第i个节气(i=0是春分)
Time
time
=
setFromJulian
(
q
,
true
);
solarTerms
[
i
-
21
]
=
time
.
toString
()
+
SOLAR_TERMS
[
i
];
}
return
solarTerms
;
}
/**
* 要获得2018年24节气需要传入2017年
*
* @param year 要获得2018年24节气需要传入2017年
* @return 返回 小寒大寒
*/
private
static
String
[]
getSolarTermsNextOffset
(
int
year
)
{
String
[]
solarTerms
=
new
String
[
2
];
double
jd
=
365.2422
*
(
year
-
2000
),
q
;
for
(
int
i
=
19
;
i
<
21
;
i
++)
{
q
=
getTimeFromAngle
(
jd
+
i
*
15.2
,
i
*
15
,
0
);
q
=
q
+
J2000
+
(
double
)
8
/
24
;
// 计算第i个节气(i=0是春分)
Time
time
=
setFromJulian
(
q
,
true
);
solarTerms
[
i
-
19
]
=
time
.
toString
()
+
SOLAR_TERMS
[
i
];
}
return
solarTerms
;
}
/**
* 章动
*/
private
static
class
Nutation
{
/**
* 章动角
*/
private
double
Lon
;
/**
* 交角
*/
private
double
Obl
;
}
private
static
class
Time
{
private
double
year
;
private
double
month
;
private
double
day
;
private
double
hour
;
private
double
minute
;
private
double
second
;
@Override
public
String
toString
()
{
return
doubleToString
(
year
)
+
doubleToString
(
month
)
+
doubleToString
(
day
);
}
}
private
static
String
doubleToString
(
double
value
)
{
int
v
=
(
int
)
value
;
return
value
<
10
?
"0"
+
v
:
String
.
valueOf
(
v
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/TrunkBranchAnnals.java
0 → 100644
View file @
335d6fe5
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
com.sobot.widget.R
;
/**
* 干支纪年算法
*/
@SuppressWarnings
(
"unused"
)
public
final
class
TrunkBranchAnnals
{
/**
* 天干字符串
*/
private
static
String
[]
TRUNK_STR
=
null
;
/**
* 地支字符串
*/
private
static
String
[]
BRANCH_STR
=
null
;
/**
* 单独使用请先调用这个方法
* @param context context
*/
public
static
void
init
(
Context
context
)
{
if
(
TRUNK_STR
!=
null
)
{
return
;
}
TRUNK_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
trunk_string_array
);
BRANCH_STR
=
context
.
getResources
().
getStringArray
(
R
.
array
.
branch_string_array
);
}
/**
* 获取某一年对应天干文字
*
* @param year 年份
* @return 天干由甲到癸,每10一轮回
*/
@SuppressWarnings
(
"all"
)
public
static
String
getTrunkString
(
int
year
)
{
return
TRUNK_STR
[
getTrunkInt
(
year
)];
}
/**
* 获取某一年对应天干,
*
* @param year 年份
* @return 4 5 6 7 8 9 10 1 2 3
*/
@SuppressWarnings
(
"all"
)
public
static
int
getTrunkInt
(
int
year
)
{
int
trunk
=
year
%
10
;
return
trunk
==
0
?
9
:
trunk
-
1
;
}
/**
* 获取某一年对应地支文字
*
* @param year 年份
* @return 地支由子到亥,每12一轮回
*/
@SuppressWarnings
(
"all"
)
public
static
String
getBranchString
(
int
year
)
{
return
BRANCH_STR
[
getBranchInt
(
year
)];
}
/**
* 获取某一年对应地支
*
* @param year 年份
* @return 4 5 6 7 8 9 10 11 12 1 2 3
*/
@SuppressWarnings
(
"all"
)
public
static
int
getBranchInt
(
int
year
)
{
int
branch
=
year
%
12
;
return
branch
==
0
?
11
:
branch
-
1
;
}
/**
* 获取干支纪年
*
* @param year 年份
* @return 干支纪年
*/
public
static
String
getTrunkBranchYear
(
int
year
)
{
return
String
.
format
(
"%s%s"
,
getTrunkString
(
year
),
getBranchString
(
year
));
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/WeekBar.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.util.TypedValue
;
import
android.view.LayoutInflater
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
import
com.sobot.widget.R
;
/**
* 星期栏,如果你要使用星期栏自定义,切记XML使用 merge,不要使用LinearLayout
*/
public
class
WeekBar
extends
LinearLayout
{
private
CalendarViewDelegate
mDelegate
;
public
WeekBar
(
Context
context
)
{
super
(
context
);
if
(
"com.haibin.calendarview.WeekBar"
.
equals
(
getClass
().
getName
()))
{
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
sobot_week_bar
,
this
,
true
);
}
}
/**
* 传递属性
*
* @param delegate delegate
*/
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
if
(
"com.haibin.calendarview.WeekBar"
.
equalsIgnoreCase
(
getClass
().
getName
()))
{
setTextSize
(
mDelegate
.
getWeekTextSize
());
setTextColor
(
delegate
.
getWeekTextColor
());
setBackgroundColor
(
delegate
.
getWeekBackground
());
setPadding
(
delegate
.
getCalendarPaddingLeft
(),
0
,
delegate
.
getCalendarPaddingRight
(),
0
);
}
}
/**
* 设置文本颜色,使用自定义布局需要重写这个方法,避免出问题
* 如果这里报错了,请确定你自定义XML文件跟布局是不是使用merge,而不是LinearLayout
*
* @param color color
*/
protected
void
setTextColor
(
int
color
)
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
((
TextView
)
getChildAt
(
i
)).
setTextColor
(
color
);
}
}
/**
* 设置文本大小
*
* @param size size
*/
protected
void
setTextSize
(
int
size
)
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
((
TextView
)
getChildAt
(
i
)).
setTextSize
(
TypedValue
.
COMPLEX_UNIT_PX
,
size
);
}
}
/**
* 日期选择事件,这里提供这个回调,可以方便定制WeekBar需要
*
* @param calendar calendar 选择的日期
* @param weekStart 周起始
* @param isClick isClick 点击
*/
protected
void
onDateSelected
(
Calendar
calendar
,
int
weekStart
,
boolean
isClick
)
{
}
/**
* 当周起始发生变化,使用自定义布局需要重写这个方法,避免出问题
*
* @param weekStart 周起始
*/
protected
void
onWeekStartChange
(
int
weekStart
)
{
if
(!
"com.haibin.calendarview.WeekBar"
.
equalsIgnoreCase
(
getClass
().
getName
()))
{
return
;
}
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
((
TextView
)
getChildAt
(
i
)).
setText
(
getWeekString
(
i
,
weekStart
));
}
}
/**
* 通过View的位置和周起始获取星期的对应坐标
*
* @param calendar calendar
* @param weekStart weekStart
* @return 通过View的位置和周起始获取星期的对应坐标
*/
protected
int
getViewIndexByCalendar
(
Calendar
calendar
,
int
weekStart
)
{
int
week
=
calendar
.
getWeek
()
+
1
;
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
)
{
return
week
-
1
;
}
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_MON
)
{
return
week
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
?
6
:
week
-
2
;
}
return
week
==
CalendarViewDelegate
.
WEEK_START_WITH_SAT
?
0
:
week
;
}
/**
* 或者周文本,这个方法仅供父类使用
*
* @param index index
* @param weekStart weekStart
* @return 或者周文本
*/
private
String
getWeekString
(
int
index
,
int
weekStart
)
{
String
[]
weeks
=
getContext
().
getResources
().
getStringArray
(
R
.
array
.
week_string_array
);
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_SUN
)
{
return
weeks
[
index
];
}
if
(
weekStart
==
CalendarViewDelegate
.
WEEK_START_WITH_MON
)
{
return
weeks
[
index
==
6
?
0
:
index
+
1
];
}
return
weeks
[
index
==
0
?
6
:
index
-
1
];
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
if
(
mDelegate
!=
null
)
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
mDelegate
.
getWeekBarHeight
(),
MeasureSpec
.
EXACTLY
);
}
else
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
CalendarUtil
.
dipToPx
(
getContext
(),
40
),
MeasureSpec
.
EXACTLY
);
}
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/WeekView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.view.View
;
/**
* 周视图,因为日历UI采用热插拔实现,所以这里必须继承实现,达到UI一致即可
*/
public
abstract
class
WeekView
extends
BaseWeekView
{
public
WeekView
(
Context
context
)
{
super
(
context
);
}
/**
* 绘制日历文本
*
* @param canvas canvas
*/
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
if
(
mItems
.
size
()
==
0
)
return
;
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getCalendarPaddingLeft
()
-
mDelegate
.
getCalendarPaddingRight
())
/
7
;
onPreviewHook
();
for
(
int
i
=
0
;
i
<
mItems
.
size
();
i
++)
{
int
x
=
i
*
mItemWidth
+
mDelegate
.
getCalendarPaddingLeft
();
onLoopStart
(
x
);
Calendar
calendar
=
mItems
.
get
(
i
);
boolean
isSelected
=
i
==
mCurrentItem
;
boolean
hasScheme
=
calendar
.
hasScheme
();
if
(
hasScheme
)
{
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
true
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
false
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
hasScheme
,
isSelected
);
}
}
@Override
public
void
onClick
(
View
v
)
{
if
(!
isClick
)
{
return
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
;
}
if
(!
isInRange
(
calendar
))
{
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarOutOfRange
(
calendar
);
}
return
;
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
true
);
}
invalidate
();
}
@Override
public
boolean
onLongClick
(
View
v
)
{
if
(
mDelegate
.
mCalendarLongClickListener
==
null
)
return
false
;
if
(!
isClick
)
{
return
false
;
}
Calendar
calendar
=
getIndex
();
if
(
calendar
==
null
)
{
return
false
;
}
if
(
onCalendarIntercept
(
calendar
))
{
mDelegate
.
mCalendarInterceptListener
.
onCalendarInterceptClick
(
calendar
,
true
);
return
true
;
}
boolean
isCalendarInRange
=
isInRange
(
calendar
);
if
(!
isCalendarInRange
)
{
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClickOutOfRange
(
calendar
);
}
return
true
;
}
if
(
mDelegate
.
isPreventLongPressedSelected
())
{
//如果启用拦截长按事件不选择日期
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClick
(
calendar
);
}
return
true
;
}
mCurrentItem
=
mItems
.
indexOf
(
calendar
);
mDelegate
.
mIndexCalendar
=
mDelegate
.
mSelectedCalendar
;
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
true
);
}
if
(
mParentLayout
!=
null
)
{
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
true
);
}
if
(
mDelegate
.
mCalendarLongClickListener
!=
null
)
{
mDelegate
.
mCalendarLongClickListener
.
onCalendarLongClick
(
calendar
);
}
invalidate
();
return
true
;
}
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return 是否绘制 onDrawScheme
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
);
/**
* 绘制标记的日期
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/WeekViewPager.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.v4.view.PagerAdapter
;
import
android.support.v4.view.ViewPager
;
import
android.util.AttributeSet
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
java.lang.reflect.Constructor
;
import
java.util.List
;
/**
* 周视图滑动ViewPager,需要动态固定高度
* 周视图是连续不断的视图,因此不能简单的得出每年都有52+1周,这样会计算重叠的部分
* WeekViewPager需要和CalendarView关联:
*/
public
final
class
WeekViewPager
extends
ViewPager
{
private
boolean
isUpdateWeekView
;
private
int
mWeekCount
;
private
CalendarViewDelegate
mDelegate
;
/**
* 日历布局,需要在日历下方放自己的布局
*/
CalendarLayout
mParentLayout
;
/**
* 是否使用滚动到某一天
*/
private
boolean
isUsingScrollToCalendar
=
false
;
public
WeekViewPager
(
Context
context
)
{
this
(
context
,
null
);
}
public
WeekViewPager
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
init
();
}
private
void
init
()
{
mWeekCount
=
CalendarUtil
.
getWeekCountBetweenBothCalendar
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
mDelegate
.
getMaxYear
(),
mDelegate
.
getMaxYearMonth
(),
mDelegate
.
getMaxYearDay
(),
mDelegate
.
getWeekStart
());
setAdapter
(
new
WeekViewPagerAdapter
());
addOnPageChangeListener
(
new
OnPageChangeListener
()
{
@Override
public
void
onPageScrolled
(
int
position
,
float
positionOffset
,
int
positionOffsetPixels
)
{
}
@Override
public
void
onPageSelected
(
int
position
)
{
//默认的显示星期四,周视图切换就显示星期4
if
(
getVisibility
()
!=
VISIBLE
)
{
isUsingScrollToCalendar
=
false
;
return
;
}
if
(
isUsingScrollToCalendar
)
{
isUsingScrollToCalendar
=
false
;
return
;
}
BaseWeekView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
performClickCalendar
(
mDelegate
.
getSelectMode
()
!=
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
?
mDelegate
.
mIndexCalendar
:
mDelegate
.
mSelectedCalendar
,
!
isUsingScrollToCalendar
);
if
(
mDelegate
.
mWeekChangeListener
!=
null
)
{
mDelegate
.
mWeekChangeListener
.
onWeekChange
(
getCurrentWeekCalendars
());
}
}
isUsingScrollToCalendar
=
false
;
}
@Override
public
void
onPageScrollStateChanged
(
int
state
)
{
}
});
}
/**
* 获取当前周数据
*
* @return 获取当前周数据
*/
List
<
Calendar
>
getCurrentWeekCalendars
()
{
List
<
Calendar
>
calendars
=
CalendarUtil
.
getWeekCalendars
(
mDelegate
.
mIndexCalendar
,
mDelegate
);
mDelegate
.
addSchemesFromMap
(
calendars
);
return
calendars
;
}
/**
* 更新周视图
*/
void
notifyDataSetChanged
()
{
mWeekCount
=
CalendarUtil
.
getWeekCountBetweenBothCalendar
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
mDelegate
.
getMaxYear
(),
mDelegate
.
getMaxYearMonth
(),
mDelegate
.
getMaxYearDay
(),
mDelegate
.
getWeekStart
());
notifyAdapterDataSetChanged
();
}
/**
* 更新周视图布局
*/
void
updateWeekViewClass
()
{
isUpdateWeekView
=
true
;
notifyAdapterDataSetChanged
();
isUpdateWeekView
=
false
;
}
/**
* 更新日期范围
*/
void
updateRange
()
{
isUpdateWeekView
=
true
;
notifyDataSetChanged
();
isUpdateWeekView
=
false
;
if
(
getVisibility
()
!=
VISIBLE
)
{
return
;
}
isUsingScrollToCalendar
=
true
;
Calendar
calendar
=
mDelegate
.
mSelectedCalendar
;
updateSelected
(
calendar
,
false
);
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
false
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
false
);
}
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
/**
* 滚动到指定日期
*
* @param year 年
* @param month 月
* @param day 日
* @param invokeListener 调用日期事件
*/
void
scrollToCalendar
(
int
year
,
int
month
,
int
day
,
boolean
smoothScroll
,
boolean
invokeListener
)
{
isUsingScrollToCalendar
=
true
;
Calendar
calendar
=
new
Calendar
();
calendar
.
setYear
(
year
);
calendar
.
setMonth
(
month
);
calendar
.
setDay
(
day
);
calendar
.
setCurrentDay
(
calendar
.
equals
(
mDelegate
.
getCurrentDay
()));
LunarCalendar
.
setupLunarCalendar
(
calendar
);
mDelegate
.
mIndexCalendar
=
calendar
;
mDelegate
.
mSelectedCalendar
=
calendar
;
mDelegate
.
updateSelectCalendarScheme
();
updateSelected
(
calendar
,
smoothScroll
);
if
(
mDelegate
.
mInnerListener
!=
null
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
calendar
,
false
);
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
invokeListener
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
calendar
,
false
);
}
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
calendar
,
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
/**
* 滚动到当前
*/
void
scrollToCurrent
(
boolean
smoothScroll
)
{
isUsingScrollToCalendar
=
true
;
int
position
=
CalendarUtil
.
getWeekFromCalendarStartWithMinCalendar
(
mDelegate
.
getCurrentDay
(),
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
mDelegate
.
getWeekStart
())
-
1
;
int
curItem
=
getCurrentItem
();
if
(
curItem
==
position
)
{
isUsingScrollToCalendar
=
false
;
}
setCurrentItem
(
position
,
smoothScroll
);
BaseWeekView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
performClickCalendar
(
mDelegate
.
getCurrentDay
(),
false
);
view
.
setSelectedCalendar
(
mDelegate
.
getCurrentDay
());
view
.
invalidate
();
}
if
(
mDelegate
.
mCalendarSelectListener
!=
null
&&
getVisibility
()
==
VISIBLE
)
{
mDelegate
.
mCalendarSelectListener
.
onCalendarSelect
(
mDelegate
.
mSelectedCalendar
,
false
);
}
if
(
getVisibility
()
==
VISIBLE
)
{
mDelegate
.
mInnerListener
.
onWeekDateSelected
(
mDelegate
.
getCurrentDay
(),
false
);
}
int
i
=
CalendarUtil
.
getWeekFromDayInMonth
(
mDelegate
.
getCurrentDay
(),
mDelegate
.
getWeekStart
());
mParentLayout
.
updateSelectWeek
(
i
);
}
/**
* 更新任意一个选择的日期
*/
void
updateSelected
(
Calendar
calendar
,
boolean
smoothScroll
)
{
int
position
=
CalendarUtil
.
getWeekFromCalendarStartWithMinCalendar
(
calendar
,
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
mDelegate
.
getWeekStart
())
-
1
;
int
curItem
=
getCurrentItem
();
isUsingScrollToCalendar
=
curItem
!=
position
;
setCurrentItem
(
position
,
smoothScroll
);
BaseWeekView
view
=
findViewWithTag
(
position
);
if
(
view
!=
null
)
{
view
.
setSelectedCalendar
(
calendar
);
view
.
invalidate
();
}
}
/**
* 更新单选模式
*/
void
updateSingleSelect
()
{
if
(
mDelegate
.
getSelectMode
()
==
CalendarViewDelegate
.
SELECT_MODE_DEFAULT
)
{
return
;
}
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateSingleSelect
();
}
}
/**
* 更新为默认选择模式
*/
void
updateDefaultSelect
()
{
BaseWeekView
view
=
findViewWithTag
(
getCurrentItem
());
if
(
view
!=
null
)
{
view
.
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
view
.
invalidate
();
}
}
/**
* 更新选择效果
*/
void
updateSelected
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
view
.
invalidate
();
}
}
/**
* 更新字体颜色大小
*/
final
void
updateStyle
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateStyle
();
view
.
invalidate
();
}
}
/**
* 更新标记日期
*/
void
updateScheme
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
update
();
}
}
/**
* 更新当前日期,夜间过度的时候调用这个函数,一般不需要调用
*/
void
updateCurrentDate
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateCurrentDate
();
}
}
/**
* 更新显示模式
*/
void
updateShowMode
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateShowMode
();
}
}
/**
* 更新周起始
*/
void
updateWeekStart
()
{
if
(
getAdapter
()
==
null
)
{
return
;
}
int
count
=
getAdapter
().
getCount
();
mWeekCount
=
CalendarUtil
.
getWeekCountBetweenBothCalendar
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
mDelegate
.
getMaxYear
(),
mDelegate
.
getMaxYearMonth
(),
mDelegate
.
getMaxYearDay
(),
mDelegate
.
getWeekStart
());
/*
* 如果count发生变化,意味着数据源变化,则必须先调用notifyDataSetChanged(),
* 否则会抛出异常
*/
if
(
count
!=
mWeekCount
)
{
isUpdateWeekView
=
true
;
getAdapter
().
notifyDataSetChanged
();
}
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateWeekStart
();
}
isUpdateWeekView
=
false
;
updateSelected
(
mDelegate
.
mSelectedCalendar
,
false
);
}
/**
* 更新高度
*/
final
void
updateItemHeight
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
updateItemHeight
();
view
.
requestLayout
();
}
}
/**
* 清除选择范围
*/
final
void
clearSelectRange
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
invalidate
();
}
}
final
void
clearSingleSelect
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
mCurrentItem
=
-
1
;
view
.
invalidate
();
}
}
final
void
clearMultiSelect
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
BaseWeekView
view
=
(
BaseWeekView
)
getChildAt
(
i
);
view
.
mCurrentItem
=
-
1
;
view
.
invalidate
();
}
}
private
void
notifyAdapterDataSetChanged
()
{
if
(
getAdapter
()
==
null
)
{
return
;
}
getAdapter
().
notifyDataSetChanged
();
}
@SuppressLint
(
"ClickableViewAccessibility"
)
@Override
public
boolean
onTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isWeekViewScrollable
()
&&
super
.
onTouchEvent
(
ev
);
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isWeekViewScrollable
()
&&
super
.
onInterceptTouchEvent
(
ev
);
}
/**
* 周视图的高度应该与日历项的高度一致
*/
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
heightMeasureSpec
=
MeasureSpec
.
makeMeasureSpec
(
mDelegate
.
getCalendarItemHeight
(),
MeasureSpec
.
EXACTLY
);
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
/**
* 周视图切换
*/
private
class
WeekViewPagerAdapter
extends
PagerAdapter
{
@Override
public
int
getCount
()
{
return
mWeekCount
;
}
@Override
public
int
getItemPosition
(
@NonNull
Object
object
)
{
return
isUpdateWeekView
?
POSITION_NONE
:
super
.
getItemPosition
(
object
);
}
@Override
public
boolean
isViewFromObject
(
@NonNull
View
view
,
@NonNull
Object
object
)
{
return
view
.
equals
(
object
);
}
@NonNull
@Override
public
Object
instantiateItem
(
@NonNull
ViewGroup
container
,
int
position
)
{
Calendar
calendar
=
CalendarUtil
.
getFirstCalendarStartWithMinCalendar
(
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMinYearDay
(),
position
+
1
,
mDelegate
.
getWeekStart
());
BaseWeekView
view
;
try
{
Constructor
constructor
=
mDelegate
.
getWeekViewClass
().
getConstructor
(
Context
.
class
);
view
=
(
BaseWeekView
)
constructor
.
newInstance
(
getContext
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
new
DefaultWeekView
(
getContext
());
}
view
.
mParentLayout
=
mParentLayout
;
view
.
setup
(
mDelegate
);
view
.
setup
(
calendar
);
view
.
setTag
(
position
);
view
.
setSelectedCalendar
(
mDelegate
.
mSelectedCalendar
);
container
.
addView
(
view
);
return
view
;
}
@Override
public
void
destroyItem
(
@NonNull
ViewGroup
container
,
int
position
,
@NonNull
Object
object
)
{
BaseWeekView
view
=
(
BaseWeekView
)
object
;
view
.
onDestroy
();
container
.
removeView
(
view
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/YearRecyclerView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.support.annotation.Nullable
;
import
android.support.v7.widget.GridLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
import
android.util.AttributeSet
;
/**
* 年份布局选择View
*/
public
final
class
YearRecyclerView
extends
RecyclerView
{
private
CalendarViewDelegate
mDelegate
;
private
YearViewAdapter
mAdapter
;
private
OnMonthSelectedListener
mListener
;
public
YearRecyclerView
(
Context
context
)
{
this
(
context
,
null
);
}
public
YearRecyclerView
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
mAdapter
=
new
YearViewAdapter
(
context
);
setLayoutManager
(
new
GridLayoutManager
(
context
,
3
));
setAdapter
(
mAdapter
);
mAdapter
.
setOnItemClickListener
(
new
BaseRecyclerAdapter
.
OnItemClickListener
()
{
@Override
public
void
onItemClick
(
int
position
,
long
itemId
)
{
if
(
mListener
!=
null
&&
mDelegate
!=
null
)
{
Month
month
=
mAdapter
.
getItem
(
position
);
if
(
month
==
null
)
{
return
;
}
if
(!
CalendarUtil
.
isMonthInRange
(
month
.
getYear
(),
month
.
getMonth
(),
mDelegate
.
getMinYear
(),
mDelegate
.
getMinYearMonth
(),
mDelegate
.
getMaxYear
(),
mDelegate
.
getMaxYearMonth
()))
{
return
;
}
mListener
.
onMonthSelected
(
month
.
getYear
(),
month
.
getMonth
());
if
(
mDelegate
.
mYearViewChangeListener
!=
null
)
{
mDelegate
.
mYearViewChangeListener
.
onYearViewChange
(
true
);
}
}
}
});
}
/**
* 设置
*
* @param delegate delegate
*/
final
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
this
.
mAdapter
.
setup
(
delegate
);
}
/**
* 初始化年视图
*
* @param year year
*/
final
void
init
(
int
year
)
{
java
.
util
.
Calendar
date
=
java
.
util
.
Calendar
.
getInstance
();
for
(
int
i
=
1
;
i
<=
12
;
i
++)
{
date
.
set
(
year
,
i
-
1
,
1
);
int
mDaysCount
=
CalendarUtil
.
getMonthDaysCount
(
year
,
i
);
Month
month
=
new
Month
();
month
.
setDiff
(
CalendarUtil
.
getMonthViewStartDiff
(
year
,
i
,
mDelegate
.
getWeekStart
()));
month
.
setCount
(
mDaysCount
);
month
.
setMonth
(
i
);
month
.
setYear
(
year
);
mAdapter
.
addItem
(
month
);
}
}
/**
* 更新周起始
*/
final
void
updateWeekStart
()
{
for
(
Month
month
:
mAdapter
.
getItems
())
{
month
.
setDiff
(
CalendarUtil
.
getMonthViewStartDiff
(
month
.
getYear
(),
month
.
getMonth
(),
mDelegate
.
getWeekStart
()));
}
}
/**
* 更新字体颜色大小
*/
final
void
updateStyle
(){
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
YearView
view
=
(
YearView
)
getChildAt
(
i
);
view
.
updateStyle
();
view
.
invalidate
();
}
}
/**
* 月份选择事件
*
* @param listener listener
*/
final
void
setOnMonthSelectedListener
(
OnMonthSelectedListener
listener
)
{
this
.
mListener
=
listener
;
}
void
notifyAdapterDataSetChanged
(){
if
(
getAdapter
()
==
null
){
return
;
}
getAdapter
().
notifyDataSetChanged
();
}
@Override
protected
void
onMeasure
(
int
widthSpec
,
int
heightSpec
)
{
super
.
onMeasure
(
widthSpec
,
heightSpec
);
int
height
=
MeasureSpec
.
getSize
(
heightSpec
);
int
width
=
MeasureSpec
.
getSize
(
widthSpec
);
mAdapter
.
setYearViewSize
(
width
/
3
,
height
/
4
);
}
interface
OnMonthSelectedListener
{
void
onMonthSelected
(
int
year
,
int
month
);
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/YearView.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.support.annotation.Nullable
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
java.util.List
;
/**
* 年视图
*/
@SuppressWarnings
(
"unused"
)
public
abstract
class
YearView
extends
View
{
CalendarViewDelegate
mDelegate
;
/**
* 当前月份日期的笔
*/
protected
Paint
mCurMonthTextPaint
=
new
Paint
();
/**
* 其它月份日期颜色
*/
protected
Paint
mOtherMonthTextPaint
=
new
Paint
();
/**
* 当前月份农历文本颜色
*/
protected
Paint
mCurMonthLunarTextPaint
=
new
Paint
();
/**
* 当前月份农历文本颜色
*/
protected
Paint
mSelectedLunarTextPaint
=
new
Paint
();
/**
* 其它月份农历文本颜色
*/
protected
Paint
mOtherMonthLunarTextPaint
=
new
Paint
();
/**
* 其它月份农历文本颜色
*/
protected
Paint
mSchemeLunarTextPaint
=
new
Paint
();
/**
* 标记的日期背景颜色画笔
*/
protected
Paint
mSchemePaint
=
new
Paint
();
/**
* 被选择的日期背景色
*/
protected
Paint
mSelectedPaint
=
new
Paint
();
/**
* 标记的文本画笔
*/
protected
Paint
mSchemeTextPaint
=
new
Paint
();
/**
* 选中的文本画笔
*/
protected
Paint
mSelectTextPaint
=
new
Paint
();
/**
* 当前日期文本颜色画笔
*/
protected
Paint
mCurDayTextPaint
=
new
Paint
();
/**
* 当前日期文本颜色画笔
*/
protected
Paint
mCurDayLunarTextPaint
=
new
Paint
();
/**
* 月份画笔
*/
protected
Paint
mMonthTextPaint
=
new
Paint
();
/**
* 周栏画笔
*/
protected
Paint
mWeekTextPaint
=
new
Paint
();
/**
* 日历项
*/
List
<
Calendar
>
mItems
;
/**
* 每一项的高度
*/
protected
int
mItemHeight
;
/**
* 每一项的宽度
*/
protected
int
mItemWidth
;
/**
* Text的基线
*/
protected
float
mTextBaseLine
;
/**
* Text的基线
*/
protected
float
mMonthTextBaseLine
;
/**
* Text的基线
*/
protected
float
mWeekTextBaseLine
;
/**
* 当前日历卡年份
*/
protected
int
mYear
;
/**
* 当前日历卡月份
*/
protected
int
mMonth
;
/**
* 下个月偏移的数量
*/
protected
int
mNextDiff
;
/**
* 周起始
*/
protected
int
mWeekStart
;
/**
* 日历的行数
*/
protected
int
mLineCount
;
public
YearView
(
Context
context
)
{
this
(
context
,
null
);
}
public
YearView
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initPaint
();
}
/**
* 初始化配置
*/
private
void
initPaint
()
{
mCurMonthTextPaint
.
setAntiAlias
(
true
);
mCurMonthTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurMonthTextPaint
.
setColor
(
0xFF111111
);
mCurMonthTextPaint
.
setFakeBoldText
(
true
);
mOtherMonthTextPaint
.
setAntiAlias
(
true
);
mOtherMonthTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mOtherMonthTextPaint
.
setColor
(
0xFFe1e1e1
);
mOtherMonthTextPaint
.
setFakeBoldText
(
true
);
mCurMonthLunarTextPaint
.
setAntiAlias
(
true
);
mCurMonthLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSelectedLunarTextPaint
.
setAntiAlias
(
true
);
mSelectedLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mOtherMonthLunarTextPaint
.
setAntiAlias
(
true
);
mOtherMonthLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mMonthTextPaint
.
setAntiAlias
(
true
);
mMonthTextPaint
.
setFakeBoldText
(
true
);
mWeekTextPaint
.
setAntiAlias
(
true
);
mWeekTextPaint
.
setFakeBoldText
(
true
);
mWeekTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeLunarTextPaint
.
setAntiAlias
(
true
);
mSchemeLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeTextPaint
.
setAntiAlias
(
true
);
mSchemeTextPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemeTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSchemeTextPaint
.
setColor
(
0xffed5353
);
mSchemeTextPaint
.
setFakeBoldText
(
true
);
mSelectTextPaint
.
setAntiAlias
(
true
);
mSelectTextPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSelectTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mSelectTextPaint
.
setColor
(
0xffed5353
);
mSelectTextPaint
.
setFakeBoldText
(
true
);
mSchemePaint
.
setAntiAlias
(
true
);
mSchemePaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSchemePaint
.
setStrokeWidth
(
2
);
mSchemePaint
.
setColor
(
0xffefefef
);
mCurDayTextPaint
.
setAntiAlias
(
true
);
mCurDayTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurDayTextPaint
.
setColor
(
Color
.
RED
);
mCurDayTextPaint
.
setFakeBoldText
(
true
);
mCurDayLunarTextPaint
.
setAntiAlias
(
true
);
mCurDayLunarTextPaint
.
setTextAlign
(
Paint
.
Align
.
CENTER
);
mCurDayLunarTextPaint
.
setColor
(
Color
.
RED
);
mCurDayLunarTextPaint
.
setFakeBoldText
(
true
);
mSelectedPaint
.
setAntiAlias
(
true
);
mSelectedPaint
.
setStyle
(
Paint
.
Style
.
FILL
);
mSelectedPaint
.
setStrokeWidth
(
2
);
}
/**
* 设置
*
* @param delegate delegate
*/
final
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
updateStyle
();
}
final
void
updateStyle
(){
if
(
mDelegate
==
null
){
return
;
}
this
.
mCurMonthTextPaint
.
setTextSize
(
mDelegate
.
getYearViewDayTextSize
());
this
.
mSchemeTextPaint
.
setTextSize
(
mDelegate
.
getYearViewDayTextSize
());
this
.
mOtherMonthTextPaint
.
setTextSize
(
mDelegate
.
getYearViewDayTextSize
());
this
.
mCurDayTextPaint
.
setTextSize
(
mDelegate
.
getYearViewDayTextSize
());
this
.
mSelectTextPaint
.
setTextSize
(
mDelegate
.
getYearViewDayTextSize
());
this
.
mSchemeTextPaint
.
setColor
(
mDelegate
.
getYearViewSchemeTextColor
());
this
.
mCurMonthTextPaint
.
setColor
(
mDelegate
.
getYearViewDayTextColor
());
this
.
mOtherMonthTextPaint
.
setColor
(
mDelegate
.
getYearViewDayTextColor
());
this
.
mCurDayTextPaint
.
setColor
(
mDelegate
.
getYearViewCurDayTextColor
());
this
.
mSelectTextPaint
.
setColor
(
mDelegate
.
getYearViewSelectTextColor
());
this
.
mMonthTextPaint
.
setTextSize
(
mDelegate
.
getYearViewMonthTextSize
());
this
.
mMonthTextPaint
.
setColor
(
mDelegate
.
getYearViewMonthTextColor
());
this
.
mWeekTextPaint
.
setColor
(
mDelegate
.
getYearViewWeekTextColor
());
this
.
mWeekTextPaint
.
setTextSize
(
mDelegate
.
getYearViewWeekTextSize
());
}
/**
* 初始化年视图
*
* @param year year
* @param month month
*/
final
void
init
(
int
year
,
int
month
)
{
mYear
=
year
;
mMonth
=
month
;
mNextDiff
=
CalendarUtil
.
getMonthEndDiff
(
mYear
,
mMonth
,
mDelegate
.
getWeekStart
());
int
preDiff
=
CalendarUtil
.
getMonthViewStartDiff
(
mYear
,
mMonth
,
mDelegate
.
getWeekStart
());
mItems
=
CalendarUtil
.
initCalendarForMonthView
(
mYear
,
mMonth
,
mDelegate
.
getCurrentDay
(),
mDelegate
.
getWeekStart
());
mLineCount
=
6
;
addSchemesFromMap
();
}
/**
* 测量大小
*
* @param width width
* @param height height
*/
@SuppressWarnings
(
"IntegerDivisionInFloatingPointContext"
)
final
void
measureSize
(
int
width
,
int
height
)
{
Rect
rect
=
new
Rect
();
mCurMonthTextPaint
.
getTextBounds
(
"1"
,
0
,
1
,
rect
);
int
textHeight
=
rect
.
height
();
int
mMinHeight
=
12
*
textHeight
+
getMonthViewTop
();
int
h
=
height
>=
mMinHeight
?
height
:
mMinHeight
;
getLayoutParams
().
width
=
width
;
getLayoutParams
().
height
=
h
;
mItemHeight
=
(
h
-
getMonthViewTop
())
/
6
;
Paint
.
FontMetrics
metrics
=
mCurMonthTextPaint
.
getFontMetrics
();
mTextBaseLine
=
mItemHeight
/
2
-
metrics
.
descent
+
(
metrics
.
bottom
-
metrics
.
top
)
/
2
;
Paint
.
FontMetrics
monthMetrics
=
mMonthTextPaint
.
getFontMetrics
();
mMonthTextBaseLine
=
mDelegate
.
getYearViewMonthHeight
()
/
2
-
monthMetrics
.
descent
+
(
monthMetrics
.
bottom
-
monthMetrics
.
top
)
/
2
;
Paint
.
FontMetrics
weekMetrics
=
mWeekTextPaint
.
getFontMetrics
();
mWeekTextBaseLine
=
mDelegate
.
getYearViewWeekHeight
()
/
2
-
weekMetrics
.
descent
+
(
weekMetrics
.
bottom
-
weekMetrics
.
top
)
/
2
;
invalidate
();
}
/**
* 添加事件标记,来自Map
*/
private
void
addSchemesFromMap
()
{
if
(
mDelegate
.
mSchemeDatesMap
==
null
||
mDelegate
.
mSchemeDatesMap
.
size
()
==
0
)
{
return
;
}
for
(
Calendar
a
:
mItems
)
{
if
(
mDelegate
.
mSchemeDatesMap
.
containsKey
(
a
.
toString
()))
{
Calendar
d
=
mDelegate
.
mSchemeDatesMap
.
get
(
a
.
toString
());
if
(
d
==
null
){
continue
;
}
a
.
setScheme
(
TextUtils
.
isEmpty
(
d
.
getScheme
())
?
mDelegate
.
getSchemeText
()
:
d
.
getScheme
());
a
.
setSchemeColor
(
d
.
getSchemeColor
());
a
.
setSchemes
(
d
.
getSchemes
());
}
else
{
a
.
setScheme
(
""
);
a
.
setSchemeColor
(
0
);
a
.
setSchemes
(
null
);
}
}
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
mItemWidth
=
(
getWidth
()
-
mDelegate
.
getYearViewMonthPaddingLeft
()
-
mDelegate
.
getYearViewMonthPaddingRight
())
/
7
;
onPreviewHook
();
onDrawMonth
(
canvas
);
onDrawWeek
(
canvas
);
onDrawMonthView
(
canvas
);
}
/**
* 绘制
*
* @param canvas canvas
*/
private
void
onDrawMonth
(
Canvas
canvas
)
{
onDrawMonth
(
canvas
,
mYear
,
mMonth
,
mDelegate
.
getYearViewMonthPaddingLeft
(),
mDelegate
.
getYearViewMonthPaddingTop
(),
getWidth
()
-
2
*
mDelegate
.
getYearViewMonthPaddingRight
(),
mDelegate
.
getYearViewMonthHeight
()
+
mDelegate
.
getYearViewMonthPaddingTop
());
}
private
int
getMonthViewTop
()
{
return
mDelegate
.
getYearViewMonthPaddingTop
()
+
mDelegate
.
getYearViewMonthHeight
()
+
mDelegate
.
getYearViewMonthPaddingBottom
()
+
mDelegate
.
getYearViewWeekHeight
();
}
/**
* 绘制
*
* @param canvas canvas
*/
private
void
onDrawWeek
(
Canvas
canvas
)
{
if
(
mDelegate
.
getYearViewWeekHeight
()
<=
0
)
{
return
;
}
int
week
=
mDelegate
.
getWeekStart
();
if
(
week
>
0
)
{
week
-=
1
;
}
int
width
=
(
getWidth
()
-
mDelegate
.
getYearViewMonthPaddingLeft
()
-
mDelegate
.
getYearViewMonthPaddingRight
())
/
7
;
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
onDrawWeek
(
canvas
,
week
,
mDelegate
.
getYearViewMonthPaddingLeft
()
+
i
*
width
,
mDelegate
.
getYearViewMonthHeight
()
+
mDelegate
.
getYearViewMonthPaddingTop
()
+
mDelegate
.
getYearViewMonthPaddingBottom
(),
width
,
mDelegate
.
getYearViewWeekHeight
());
week
+=
1
;
if
(
week
>=
7
)
{
week
=
0
;
}
}
}
/**
* 绘制月份数据
*
* @param canvas canvas
*/
private
void
onDrawMonthView
(
Canvas
canvas
)
{
int
count
=
mLineCount
*
7
;
int
d
=
0
;
for
(
int
i
=
0
;
i
<
mLineCount
;
i
++)
{
for
(
int
j
=
0
;
j
<
7
;
j
++)
{
Calendar
calendar
=
mItems
.
get
(
d
);
if
(
d
>
mItems
.
size
()
-
mNextDiff
)
{
return
;
}
if
(!
calendar
.
isCurrentMonth
())
{
++
d
;
continue
;
}
draw
(
canvas
,
calendar
,
i
,
j
,
d
);
++
d
;
}
}
}
/**
* 开始绘制
*
* @param canvas canvas
* @param calendar 对应日历
* @param i i
* @param j j
* @param d d
*/
private
void
draw
(
Canvas
canvas
,
Calendar
calendar
,
int
i
,
int
j
,
int
d
)
{
int
x
=
j
*
mItemWidth
+
mDelegate
.
getYearViewMonthPaddingLeft
();
int
y
=
i
*
mItemHeight
+
getMonthViewTop
();
boolean
isSelected
=
calendar
.
equals
(
mDelegate
.
mSelectedCalendar
);
boolean
hasScheme
=
calendar
.
hasScheme
();
if
(
hasScheme
)
{
//标记的日子
boolean
isDrawSelected
=
false
;
//是否继续绘制选中的onDrawScheme
if
(
isSelected
)
{
isDrawSelected
=
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
true
);
}
if
(
isDrawSelected
||
!
isSelected
)
{
//将画笔设置为标记颜色
mSchemePaint
.
setColor
(
calendar
.
getSchemeColor
()
!=
0
?
calendar
.
getSchemeColor
()
:
mDelegate
.
getSchemeThemeColor
());
onDrawScheme
(
canvas
,
calendar
,
x
,
y
);
}
}
else
{
if
(
isSelected
)
{
onDrawSelected
(
canvas
,
calendar
,
x
,
y
,
false
);
}
}
onDrawText
(
canvas
,
calendar
,
x
,
y
,
hasScheme
,
isSelected
);
}
/**
* 开始绘制前的钩子,这里做一些初始化的操作,每次绘制只调用一次,性能高效
* 没有需要可忽略不实现
* 例如:
* 1、需要绘制圆形标记事件背景,可以在这里计算半径
* 2、绘制矩形选中效果,也可以在这里计算矩形宽和高
*/
protected
void
onPreviewHook
()
{
// TODO: 2017/11/16
}
/**
* 绘制月份
*
* @param canvas canvas
* @param year year
* @param month month
* @param x x
* @param y y
* @param width width
* @param height height
*/
protected
abstract
void
onDrawMonth
(
Canvas
canvas
,
int
year
,
int
month
,
int
x
,
int
y
,
int
width
,
int
height
);
/**
* 绘制年视图的周栏
*
* @param canvas canvas
* @param week week
* @param x x
* @param y y
* @param width width
* @param height height
*/
protected
abstract
void
onDrawWeek
(
Canvas
canvas
,
int
week
,
int
x
,
int
y
,
int
width
,
int
height
);
/**
* 绘制选中的日期
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return 是否绘制onDrawScheme,true or false
*/
protected
abstract
boolean
onDrawSelected
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
);
/**
* 绘制标记的日期,这里可以是背景色,标记色什么的
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
*/
protected
abstract
void
onDrawScheme
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
);
/**
* 绘制日历文本
*
* @param canvas canvas
* @param calendar 日历calendar
* @param x 日历Card x起点坐标
* @param y 日历Card y起点坐标
* @param hasScheme 是否是标记的日期
* @param isSelected 是否选中
*/
protected
abstract
void
onDrawText
(
Canvas
canvas
,
Calendar
calendar
,
int
x
,
int
y
,
boolean
hasScheme
,
boolean
isSelected
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/YearViewAdapter.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.content.Context
;
import
android.support.v7.widget.RecyclerView
;
import
android.text.TextUtils
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
java.lang.reflect.Constructor
;
final
class
YearViewAdapter
extends
BaseRecyclerAdapter
<
Month
>
{
private
CalendarViewDelegate
mDelegate
;
private
int
mItemWidth
,
mItemHeight
;
YearViewAdapter
(
Context
context
)
{
super
(
context
);
}
final
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
}
final
void
setYearViewSize
(
int
width
,
int
height
)
{
this
.
mItemWidth
=
width
;
this
.
mItemHeight
=
height
;
}
@Override
RecyclerView
.
ViewHolder
onCreateDefaultViewHolder
(
ViewGroup
parent
,
int
type
)
{
YearView
yearView
;
if
(
TextUtils
.
isEmpty
(
mDelegate
.
getYearViewClassPath
()))
{
yearView
=
new
DefaultYearView
(
mContext
);
}
else
{
try
{
Constructor
constructor
=
mDelegate
.
getYearViewClass
().
getConstructor
(
Context
.
class
);
yearView
=
(
YearView
)
constructor
.
newInstance
(
mContext
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
yearView
=
new
DefaultYearView
(
mContext
);
}
}
RecyclerView
.
LayoutParams
params
=
new
RecyclerView
.
LayoutParams
(
RecyclerView
.
LayoutParams
.
MATCH_PARENT
,
RecyclerView
.
LayoutParams
.
MATCH_PARENT
);
yearView
.
setLayoutParams
(
params
);
return
new
YearViewHolder
(
yearView
,
mDelegate
);
}
@Override
void
onBindViewHolder
(
RecyclerView
.
ViewHolder
holder
,
Month
item
,
int
position
)
{
YearViewHolder
h
=
(
YearViewHolder
)
holder
;
YearView
view
=
h
.
mYearView
;
view
.
init
(
item
.
getYear
(),
item
.
getMonth
());
view
.
measureSize
(
mItemWidth
,
mItemHeight
);
}
private
static
class
YearViewHolder
extends
RecyclerView
.
ViewHolder
{
YearView
mYearView
;
YearViewHolder
(
View
itemView
,
CalendarViewDelegate
delegate
)
{
super
(
itemView
);
mYearView
=
(
YearView
)
itemView
;
mYearView
.
setup
(
delegate
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/ui/calenderview/YearViewPager.java
0 → 100644
View file @
335d6fe5
/*
* Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
* WebSite https://github.com/MiracleTimes-Dev
* 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.
*/
package
com
.
sobot
.
widget
.
ui
.
calenderview
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.v4.view.PagerAdapter
;
import
android.support.v4.view.ViewPager
;
import
android.util.AttributeSet
;
import
android.view.Display
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.view.WindowManager
;
/**
* 年份+月份选择布局
* ViewPager + RecyclerView
*/
public
final
class
YearViewPager
extends
ViewPager
{
private
int
mYearCount
;
private
boolean
isUpdateYearView
;
private
CalendarViewDelegate
mDelegate
;
private
YearRecyclerView
.
OnMonthSelectedListener
mListener
;
public
YearViewPager
(
Context
context
)
{
this
(
context
,
null
);
}
public
YearViewPager
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
void
setup
(
CalendarViewDelegate
delegate
)
{
this
.
mDelegate
=
delegate
;
this
.
mYearCount
=
mDelegate
.
getMaxYear
()
-
mDelegate
.
getMinYear
()
+
1
;
setAdapter
(
new
PagerAdapter
()
{
@Override
public
int
getCount
()
{
return
mYearCount
;
}
@Override
public
int
getItemPosition
(
@NonNull
Object
object
)
{
return
isUpdateYearView
?
POSITION_NONE
:
super
.
getItemPosition
(
object
);
}
@Override
public
boolean
isViewFromObject
(
@NonNull
View
view
,
@NonNull
Object
object
)
{
return
view
==
object
;
}
@NonNull
@Override
public
Object
instantiateItem
(
@NonNull
ViewGroup
container
,
int
position
)
{
YearRecyclerView
view
=
new
YearRecyclerView
(
getContext
());
container
.
addView
(
view
);
view
.
setup
(
mDelegate
);
view
.
setOnMonthSelectedListener
(
mListener
);
view
.
init
(
position
+
mDelegate
.
getMinYear
());
return
view
;
}
@Override
public
void
destroyItem
(
@NonNull
ViewGroup
container
,
int
position
,
@NonNull
Object
object
)
{
container
.
removeView
((
View
)
object
);
}
});
setCurrentItem
(
mDelegate
.
getCurrentDay
().
getYear
()
-
mDelegate
.
getMinYear
());
}
@Override
public
void
setCurrentItem
(
int
item
)
{
setCurrentItem
(
item
,
false
);
}
@Override
public
void
setCurrentItem
(
int
item
,
boolean
smoothScroll
)
{
if
(
Math
.
abs
(
getCurrentItem
()
-
item
)
>
1
)
{
super
.
setCurrentItem
(
item
,
false
);
}
else
{
super
.
setCurrentItem
(
item
,
false
);
}
}
/**
* 通知刷新
*/
void
notifyDataSetChanged
()
{
this
.
mYearCount
=
mDelegate
.
getMaxYear
()
-
mDelegate
.
getMinYear
()
+
1
;
if
(
getAdapter
()
!=
null
){
getAdapter
().
notifyDataSetChanged
();
}
}
/**
* 滚动到某年
*
* @param year year
* @param smoothScroll smoothScroll
*/
void
scrollToYear
(
int
year
,
boolean
smoothScroll
)
{
setCurrentItem
(
year
-
mDelegate
.
getMinYear
(),
smoothScroll
);
}
/**
* 更新日期范围
*/
final
void
updateRange
()
{
isUpdateYearView
=
true
;
notifyDataSetChanged
();
isUpdateYearView
=
false
;
}
/**
* 更新界面
*/
final
void
update
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
YearRecyclerView
view
=
(
YearRecyclerView
)
getChildAt
(
i
);
view
.
notifyAdapterDataSetChanged
();
}
}
/**
* 更新周起始
*/
final
void
updateWeekStart
()
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
YearRecyclerView
view
=
(
YearRecyclerView
)
getChildAt
(
i
);
view
.
updateWeekStart
();
view
.
notifyAdapterDataSetChanged
();
}
}
/**
* 更新字体颜色大小
*/
final
void
updateStyle
(){
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
YearRecyclerView
view
=
(
YearRecyclerView
)
getChildAt
(
i
);
view
.
updateStyle
();
}
}
final
void
setOnMonthSelectedListener
(
YearRecyclerView
.
OnMonthSelectedListener
listener
)
{
this
.
mListener
=
listener
;
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
//heightMeasureSpec = MeasureSpec.makeMeasureSpec(getHeight(getContext(), this), MeasureSpec.EXACTLY);
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
}
/**
* 计算相对高度
*
* @param context context
* @param view view
* @return 年月视图选择器最适合的高度
*/
private
static
int
getHeight
(
Context
context
,
View
view
)
{
WindowManager
manager
=
(
WindowManager
)
context
.
getSystemService
(
Context
.
WINDOW_SERVICE
);
assert
manager
!=
null
;
Display
display
=
manager
.
getDefaultDisplay
();
int
h
=
display
.
getHeight
();
int
[]
location
=
new
int
[
2
];
view
.
getLocationInWindow
(
location
);
view
.
getLocationOnScreen
(
location
);
return
h
-
location
[
1
];
}
@SuppressLint
(
"ClickableViewAccessibility"
)
@Override
public
boolean
onTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isYearViewScrollable
()
&&
super
.
onTouchEvent
(
ev
);
}
@Override
public
boolean
onInterceptTouchEvent
(
MotionEvent
ev
)
{
return
mDelegate
.
isYearViewScrollable
()
&&
super
.
onInterceptTouchEvent
(
ev
);
}
}
sobot_widget/src/main/res/layout/sobot_custom_week_bar.xml
0 → 100644
View file @
335d6fe5
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/ll_week"
android:layout_width=
"match_parent"
android:layout_height=
"40dp"
android:background=
"#FFFFFF"
android:minHeight=
"40dp"
android:orientation=
"horizontal"
android:paddingBottom=
"8dp"
android:paddingTop=
"8dp"
tools:ignore=
"HardcodedText"
>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/sun"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/mon"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/tue"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/wed"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/thu"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/fri"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/sat"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
</merge>
\ No newline at end of file
sobot_widget/src/main/res/layout/sobot_layout_calendar_view.xml
0 → 100644
View file @
335d6fe5
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
tools:ignore=
"HardcodedText"
>
<FrameLayout
android:id=
"@+id/frameContent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
android:visibility=
"visible"
>
<com.sobot.widget.ui.calenderview.MonthViewPager
android:id=
"@+id/vp_month"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"41dp"
/>
<com.sobot.widget.ui.calenderview.WeekViewPager
android:id=
"@+id/vp_week"
android:layout_width=
"match_parent"
android:layout_height=
"50dp"
android:layout_marginTop=
"41dp"
android:visibility=
"gone"
/>
<View
android:id=
"@+id/line"
android:layout_width=
"match_parent"
android:layout_height=
"1px"
android:layout_marginLeft=
"16dp"
android:layout_marginRight=
"16dp"
android:layout_marginTop=
"40dp"
android:background=
"#cfcfcf"
/>
</FrameLayout>
<com.sobot.widget.ui.calenderview.YearViewPager
android:id=
"@+id/selectLayout"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"#ffffff"
android:visibility=
"gone"
/>
</merge>
\ No newline at end of file
sobot_widget/src/main/res/layout/sobot_week_bar.xml
0 → 100644
View file @
335d6fe5
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/ll_week"
android:layout_width=
"match_parent"
android:layout_height=
"40dp"
android:background=
"#FFFFFF"
android:minHeight=
"40dp"
android:orientation=
"horizontal"
android:paddingBottom=
"8dp"
android:paddingTop=
"8dp"
tools:ignore=
"HardcodedText"
>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/sun"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/mon"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/tue"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/wed"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/thu"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/fri"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:gravity=
"center"
android:text=
"@string/sat"
android:textColor=
"#333333"
android:textSize=
"12sp"
/>
</merge>
\ No newline at end of file
sobot_widget/src/main/res/values-en/strings_calender.xml
0 → 100644
View file @
335d6fe5
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools=
"http://schemas.android.com/tools"
>
<string-array
name=
"lunar_first_of_month"
>
<item>
春节
</item>
<item>
二月
</item>
<item>
三月
</item>
<item>
四月
</item>
<item>
五月
</item>
<item>
六月
</item>
<item>
七月
</item>
<item>
八月
</item>
<item>
九月
</item>
<item>
十月
</item>
<item>
冬月
</item>
<item>
腊月
</item>
</string-array>
<string-array
name=
"tradition_festival"
>
<item>
除夕
</item>
<item>
0101春节
</item>
<item>
0115元宵
</item>
<item>
0505端午
</item>
<item>
0707七夕
</item>
<item>
0815中秋
</item>
<item>
0909重阳
</item>
</string-array>
<string-array
name=
"lunar_str"
>
<item>
初一
</item>
<item>
初二
</item>
<item>
初三
</item>
<item>
初四
</item>
<item>
初五
</item>
<item>
初六
</item>
<item>
初七
</item>
<item>
初八
</item>
<item>
初九
</item>
<item>
初十
</item>
<item>
十一
</item>
<item>
十二
</item>
<item>
十三
</item>
<item>
十四
</item>
<item>
十五
</item>
<item>
十六
</item>
<item>
十七
</item>
<item>
十八
</item>
<item>
十九
</item>
<item>
二十
</item>
<item>
廿一
</item>
<item>
廿二
</item>
<item>
廿三
</item>
<item>
廿四
</item>
<item>
廿五
</item>
<item>
廿六
</item>
<item>
廿七
</item>
<item>
廿八
</item>
<item>
廿九
</item>
<item>
三十
</item>
</string-array>
<string-array
name=
"solar_festival"
tools:ignore=
"InconsistentArrays"
>
<item>
0101元旦
</item>
<item>
0214情人节
</item>
<item>
0308妇女节
</item>
<item>
0312植树节
</item>
<item>
0315消权日
</item>
<item>
0401愚人节
</item>
<item>
0422地球日
</item>
<item>
0501劳动节
</item>
<item>
0504青年节
</item>
<item>
0601儿童节
</item>
<item>
0701建党节
</item>
<item>
0801建军节
</item>
<item>
0910教师节
</item>
<item>
1001国庆节
</item>
<item>
1031万圣节
</item>
<item>
1111光棍节
</item>
<item>
1224平安夜
</item>
<item>
1225圣诞节
</item>
</string-array>
<string-array
name=
"solar_term"
>
<item>
春分
</item>
<item>
清明
</item>
<item>
谷雨
</item>
<item>
立夏
</item>
<item>
小满
</item>
<item>
芒种
</item>
<item>
夏至
</item>
<item>
小暑
</item>
<item>
大暑
</item>
<item>
立秋
</item>
<item>
处暑
</item>
<item>
白露
</item>
<item>
秋分
</item>
<item>
寒露
</item>
<item>
霜降
</item>
<item>
立冬
</item>
<item>
小雪
</item>
<item>
大雪
</item>
<item>
冬至
</item>
<item>
小寒
</item>
<item>
大寒
</item>
<item>
立春
</item>
<item>
雨水
</item>
<item>
惊蛰
</item>
</string-array>
<string-array
name=
"special_festivals"
>
<item>
母亲节
</item>
<item>
父亲节
</item>
<item>
感恩节
</item>
</string-array>
<string
name=
"sun"
>
Sun
</string>
<string
name=
"mon"
>
Mon
</string>
<string
name=
"tue"
>
Tue
</string>
<string
name=
"wed"
>
Wed
</string>
<string
name=
"thu"
>
Thu
</string>
<string
name=
"fri"
>
Fri
</string>
<string
name=
"sat"
>
Sat
</string>
<string-array
name=
"week_string_array"
>
<item>
Sun
</item>
<item>
Mon
</item>
<item>
Tue
</item>
<item>
Wed
</item>
<item>
Thu
</item>
<item>
Fri
</item>
<item>
Sat
</item>
</string-array>
<string-array
name=
"year_view_week_string_array"
>
<item>
S
</item>
<item>
M
</item>
<item>
T
</item>
<item>
W
</item>
<item>
T
</item>
<item>
F
</item>
<item>
S
</item>
</string-array>
<string-array
name=
"month_string_array"
>
<item>
JAN
</item>
<item>
FEB
</item>
<item>
MAR
</item>
<item>
APR
</item>
<item>
MAY
</item>
<item>
JUN
</item>
<item>
JUL
</item>
<item>
AUG
</item>
<item>
SEP
</item>
<item>
OCT
</item>
<item>
NOV
</item>
<item>
DEC
</item>
</string-array>
<integer-array
name=
"trunk_integer_array"
>
<item>
1
</item>
<item>
2
</item>
<item>
3
</item>
<item>
4
</item>
<item>
5
</item>
<item>
6
</item>
<item>
7
</item>
<item>
8
</item>
<item>
9
</item>
<item>
10
</item>
</integer-array>
<string-array
name=
"trunk_string_array"
>
<item>
辛
</item>
<item>
壬
</item>
<item>
癸
</item>
<item>
甲
</item>
<item>
乙
</item>
<item>
丙
</item>
<item>
丁
</item>
<item>
戊
</item>
<item>
己
</item>
<item>
庚
</item>
</string-array>
<integer-array
name=
"branch_integer_array"
>
<item>
1
</item>
<item>
2
</item>
<item>
3
</item>
<item>
4
</item>
<item>
5
</item>
<item>
6
</item>
<item>
7
</item>
<item>
8
</item>
<item>
9
</item>
<item>
10
</item>
<item>
11
</item>
<item>
12
</item>
</integer-array>
<string-array
name=
"branch_string_array"
>
<item>
酉
</item>
<item>
戌
</item>
<item>
亥
</item>
<item>
子
</item>
<item>
丑
</item>
<item>
寅
</item>
<item>
卯
</item>
<item>
辰
</item>
<item>
巳
</item>
<item>
午
</item>
<item>
未
</item>
<item>
申
</item>
</string-array>
</resources>
\ No newline at end of file
sobot_widget/src/main/res/values/attrs.xml
View file @
335d6fe5
...
...
@@ -245,4 +245,145 @@
<attr
name=
"sobot_stroke_width"
/>
<attr
name=
"sobot_clip_background"
/>
</declare-styleable>
<declare-styleable
name=
"Sobot_CalendarView"
>
<attr
name=
"calendar_padding"
format=
"dimension"
/>
<!--日历内部左右padding-->
<attr
name=
"calendar_padding_left"
format=
"dimension"
/>
<!--日历内部左padding-->
<attr
name=
"calendar_padding_right"
format=
"dimension"
/>
<!--日历内部右padding-->
<attr
name=
"week_background"
format=
"color"
/>
<!--周背景-->
<attr
name=
"week_line_background"
format=
"color"
/>
<!--线条颜色-->
<attr
name=
"week_text_color"
format=
"color"
/>
<!--周栏字体颜色-->
<attr
name=
"week_text_size"
format=
"dimension"
/>
<!--周栏字体大小-->
<attr
name=
"week_line_margin"
format=
"dimension"
/>
<!--线条margin-->
<attr
name=
"month_view"
format=
"string"
/>
<!--完全自定义月视图-->
<attr
name=
"week_view"
format=
"string"
/>
<!--完全自定义周视图-->
<attr
name=
"year_view"
format=
"string"
/>
<!--完全自定义年视图-->
<attr
name=
"week_bar_height"
format=
"dimension"
/>
<!--星期栏的高度-->
<attr
name=
"week_bar_view"
format=
"string"
/>
<!--如果需要的话使用自定义星期栏-->
<attr
name=
"scheme_text"
format=
"string"
/>
<attr
name=
"day_text_size"
format=
"dimension"
/>
<attr
name=
"lunar_text_size"
format=
"dimension"
/>
<attr
name=
"calendar_height"
format=
"dimension"
/>
<attr
name=
"calendar_match_parent"
format=
"boolean"
/>
<!-- 全屏日历 -->
<attr
name=
"scheme_text_color"
format=
"color"
/>
<attr
name=
"scheme_month_text_color"
format=
"color"
/>
<attr
name=
"scheme_lunar_text_color"
format=
"color"
/>
<attr
name=
"scheme_theme_color"
format=
"color"
/>
<attr
name=
"selected_theme_color"
format=
"color"
/>
<attr
name=
"selected_text_color"
format=
"color"
/>
<attr
name=
"selected_lunar_text_color"
format=
"color"
/>
<attr
name=
"current_day_text_color"
format=
"color"
/>
<attr
name=
"current_day_lunar_text_color"
format=
"color"
/>
<attr
name=
"current_month_text_color"
format=
"color"
/>
<attr
name=
"other_month_text_color"
format=
"color"
/>
<attr
name=
"current_month_lunar_text_color"
format=
"color"
/>
<attr
name=
"other_month_lunar_text_color"
format=
"color"
/>
<!-- 年视图相关 -->
<attr
name=
"year_view_month_text_size"
format=
"dimension"
/>
<attr
name=
"year_view_day_text_size"
format=
"dimension"
/>
<attr
name=
"year_view_month_text_color"
format=
"color"
/>
<attr
name=
"year_view_current_day_text_color"
format=
"color"
/>
<attr
name=
"year_view_day_text_color"
format=
"color"
/>
<attr
name=
"year_view_select_text_color"
format=
"color"
/>
<attr
name=
"year_view_scheme_color"
format=
"color"
/>
<attr
name=
"year_view_background"
format=
"color"
/>
<attr
name=
"year_view_month_height"
format=
"dimension"
/>
<attr
name=
"year_view_week_height"
format=
"dimension"
/>
<attr
name=
"year_view_week_text_size"
format=
"dimension"
/>
<attr
name=
"year_view_week_text_color"
format=
"color"
/>
<attr
name=
"year_view_padding"
format=
"dimension"
/>
<attr
name=
"year_view_padding_left"
format=
"dimension"
/>
<attr
name=
"year_view_padding_right"
format=
"dimension"
/>
<attr
name=
"year_view_month_padding_top"
format=
"dimension"
/>
<attr
name=
"year_view_month_padding_left"
format=
"dimension"
/>
<attr
name=
"year_view_month_padding_right"
format=
"dimension"
/>
<attr
name=
"year_view_month_padding_bottom"
format=
"dimension"
/>
<!--日期范围-->
<attr
name=
"min_year"
format=
"integer"
/>
<attr
name=
"max_year"
format=
"integer"
/>
<attr
name=
"min_year_month"
format=
"integer"
/>
<attr
name=
"max_year_month"
format=
"integer"
/>
<attr
name=
"min_year_day"
format=
"integer"
/>
<attr
name=
"max_year_day"
format=
"integer"
/>
<!--月视图是否可滚动-->
<attr
name=
"month_view_scrollable"
format=
"boolean"
/>
<!--周视图是否可滚动-->
<attr
name=
"week_view_scrollable"
format=
"boolean"
/>
<!--年视图是否可滚动-->
<attr
name=
"year_view_scrollable"
format=
"boolean"
/>
<!-- 月份显示模式 -->
<attr
name=
"month_view_show_mode"
>
<enum
name=
"mode_all"
value=
"0"
/>
<enum
name=
"mode_only_current"
value=
"1"
/>
<enum
name=
"mode_fix"
value=
"2"
/>
</attr>
<!-- 自定义周起始 -->
<attr
name=
"week_start_with"
>
<enum
name=
"sun"
value=
"1"
/>
<enum
name=
"mon"
value=
"2"
/>
<enum
name=
"sat"
value=
"7"
/>
</attr>
<!-- 自定义选择模式 -->
<attr
name=
"select_mode"
>
<enum
name=
"default_mode"
value=
"0"
/>
<enum
name=
"single_mode"
value=
"1"
/>
<enum
name=
"range_mode"
value=
"2"
/>
<enum
name=
"multi_mode"
value=
"3"
/>
</attr>
<!-- when select_mode = multi_mode -->
<attr
name=
"max_multi_select_size"
format=
"integer"
/>
<!-- when select_mode = range_mode -->
<attr
name=
"min_select_range"
format=
"integer"
/>
<attr
name=
"max_select_range"
format=
"integer"
/>
<!-- auto select day -->
<attr
name=
"month_view_auto_select_day"
>
<enum
name=
"first_day_of_month"
value=
"0"
/>
<enum
name=
"last_select_day"
value=
"1"
/>
<enum
name=
"last_select_day_ignore_current"
value=
"2"
/>
</attr>
</declare-styleable>
<declare-styleable
name=
"Sobot_CalendarLayout"
>
<attr
name=
"default_status"
>
<enum
name=
"expand"
value=
"0"
/>
<enum
name=
"shrink"
value=
"1"
/>
</attr>
<!-- 手势模式 -->
<attr
name=
"gesture_mode"
>
<enum
name=
"default_mode"
value=
"0"
/>
<!--<enum name="only_calendar" value="1" />-->
<enum
name=
"disabled"
value=
"2"
/>
</attr>
<attr
name=
"calendar_show_mode"
>
<enum
name=
"both_month_week_view"
value=
"0"
/>
<enum
name=
"only_week_view"
value=
"1"
/>
<enum
name=
"only_month_view"
value=
"2"
/>
</attr>
<attr
name=
"calendar_content_view_id"
format=
"integer"
/>
</declare-styleable>
</resources>
\ No newline at end of file
sobot_widget/src/main/res/values/strings_calender.xml
0 → 100644
View file @
335d6fe5
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools=
"http://schemas.android.com/tools"
>
<string-array
name=
"lunar_first_of_month"
>
<item>
春节
</item>
<item>
二月
</item>
<item>
三月
</item>
<item>
四月
</item>
<item>
五月
</item>
<item>
六月
</item>
<item>
七月
</item>
<item>
八月
</item>
<item>
九月
</item>
<item>
十月
</item>
<item>
冬月
</item>
<item>
腊月
</item>
</string-array>
<string-array
name=
"tradition_festival"
>
<item>
除夕
</item>
<item>
0101春节
</item>
<item>
0115元宵
</item>
<item>
0505端午
</item>
<item>
0707七夕
</item>
<item>
0815中秋
</item>
<item>
0909重阳
</item>
</string-array>
<string-array
name=
"lunar_str"
>
<item>
初一
</item>
<item>
初二
</item>
<item>
初三
</item>
<item>
初四
</item>
<item>
初五
</item>
<item>
初六
</item>
<item>
初七
</item>
<item>
初八
</item>
<item>
初九
</item>
<item>
初十
</item>
<item>
十一
</item>
<item>
十二
</item>
<item>
十三
</item>
<item>
十四
</item>
<item>
十五
</item>
<item>
十六
</item>
<item>
十七
</item>
<item>
十八
</item>
<item>
十九
</item>
<item>
二十
</item>
<item>
廿一
</item>
<item>
廿二
</item>
<item>
廿三
</item>
<item>
廿四
</item>
<item>
廿五
</item>
<item>
廿六
</item>
<item>
廿七
</item>
<item>
廿八
</item>
<item>
廿九
</item>
<item>
三十
</item>
</string-array>
<string-array
name=
"solar_festival"
tools:ignore=
"InconsistentArrays"
>
<item>
0101元旦
</item>
<item>
0214情人节
</item>
<item>
0308妇女节
</item>
<item>
0312植树节
</item>
<item>
0315消权日
</item>
<item>
0401愚人节
</item>
<item>
0422地球日
</item>
<item>
0501劳动节
</item>
<item>
0504青年节
</item>
<item>
0601儿童节
</item>
<item>
0701建党节
</item>
<item>
0801建军节
</item>
<item>
0910教师节
</item>
<item>
1001国庆节
</item>
<item>
1031万圣节
</item>
<item>
1111光棍节
</item>
<item>
1224平安夜
</item>
<item>
1225圣诞节
</item>
</string-array>
<string-array
name=
"solar_term"
>
<item>
春分
</item>
<item>
清明
</item>
<item>
谷雨
</item>
<item>
立夏
</item>
<item>
小满
</item>
<item>
芒种
</item>
<item>
夏至
</item>
<item>
小暑
</item>
<item>
大暑
</item>
<item>
立秋
</item>
<item>
处暑
</item>
<item>
白露
</item>
<item>
秋分
</item>
<item>
寒露
</item>
<item>
霜降
</item>
<item>
立冬
</item>
<item>
小雪
</item>
<item>
大雪
</item>
<item>
冬至
</item>
<item>
小寒
</item>
<item>
大寒
</item>
<item>
立春
</item>
<item>
雨水
</item>
<item>
惊蛰
</item>
</string-array>
<string-array
name=
"special_festivals"
>
<item>
母亲节
</item>
<item>
父亲节
</item>
<item>
感恩节
</item>
</string-array>
<string
name=
"sun"
>
日
</string>
<string
name=
"mon"
>
一
</string>
<string
name=
"tue"
>
二
</string>
<string
name=
"wed"
>
三
</string>
<string
name=
"thu"
>
四
</string>
<string
name=
"fri"
>
五
</string>
<string
name=
"sat"
>
六
</string>
<string-array
name=
"week_string_array"
>
<item>
周日
</item>
<item>
周一
</item>
<item>
周二
</item>
<item>
周三
</item>
<item>
周四
</item>
<item>
周五
</item>
<item>
周六
</item>
</string-array>
<string-array
name=
"year_view_week_string_array"
>
<item>
日
</item>
<item>
一
</item>
<item>
二
</item>
<item>
三
</item>
<item>
四
</item>
<item>
五
</item>
<item>
六
</item>
</string-array>
<string-array
name=
"month_string_array"
>
<item>
1月
</item>
<item>
2月
</item>
<item>
3月
</item>
<item>
4月
</item>
<item>
5月
</item>
<item>
6月
</item>
<item>
7月
</item>
<item>
8月
</item>
<item>
9月
</item>
<item>
10月
</item>
<item>
11月
</item>
<item>
12月
</item>
</string-array>
<integer-array
name=
"trunk_integer_array"
>
<item>
1
</item>
<item>
2
</item>
<item>
3
</item>
<item>
4
</item>
<item>
5
</item>
<item>
6
</item>
<item>
7
</item>
<item>
8
</item>
<item>
9
</item>
<item>
10
</item>
</integer-array>
<string-array
name=
"trunk_string_array"
>
<item>
辛
</item>
<item>
壬
</item>
<item>
癸
</item>
<item>
甲
</item>
<item>
乙
</item>
<item>
丙
</item>
<item>
丁
</item>
<item>
戊
</item>
<item>
己
</item>
<item>
庚
</item>
</string-array>
<integer-array
name=
"branch_integer_array"
>
<item>
1
</item>
<item>
2
</item>
<item>
3
</item>
<item>
4
</item>
<item>
5
</item>
<item>
6
</item>
<item>
7
</item>
<item>
8
</item>
<item>
9
</item>
<item>
10
</item>
<item>
11
</item>
<item>
12
</item>
</integer-array>
<string-array
name=
"branch_string_array"
>
<item>
酉
</item>
<item>
戌
</item>
<item>
亥
</item>
<item>
子
</item>
<item>
丑
</item>
<item>
寅
</item>
<item>
卯
</item>
<item>
辰
</item>
<item>
巳
</item>
<item>
午
</item>
<item>
未
</item>
<item>
申
</item>
</string-array>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment